blob: 3f1a677a729a7c337ec1c9aec8558a099f629a85 [file] [log] [blame]
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "Camera2Client"
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070018#define ATRACE_TAG ATRACE_TAG_CAMERA
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070019//#define LOG_NDEBUG 0
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070020
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070021#include <utils/Log.h>
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070022#include <utils/Trace.h>
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070023
24#include <cutils/properties.h>
25#include <gui/SurfaceTextureClient.h>
26#include <gui/Surface.h>
Eino-Ville Talvala78822d72012-07-18 17:52:18 -070027#include <media/hardware/MetadataBufferType.h>
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070028
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070029#include <math.h>
30
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070031#include "Camera2Client.h"
32
33namespace android {
34
35#define ALOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__);
36#define ALOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__);
37
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070038static int getCallingPid() {
39 return IPCThreadState::self()->getCallingPid();
40}
41
42static int getCallingUid() {
43 return IPCThreadState::self()->getCallingUid();
44}
45
46// Interface used by CameraService
47
48Camera2Client::Camera2Client(const sp<CameraService>& cameraService,
49 const sp<ICameraClient>& cameraClient,
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070050 int cameraId,
51 int cameraFacing,
52 int clientPid):
53 Client(cameraService, cameraClient,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070054 cameraId, cameraFacing, clientPid),
Eino-Ville Talvala3a609142012-07-31 14:36:26 -070055 mState(DISCONNECTED),
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -070056 mPreviewStreamId(NO_STREAM),
57 mPreviewRequest(NULL),
58 mCaptureStreamId(NO_STREAM),
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -070059 mCaptureRequest(NULL),
60 mRecordingStreamId(NO_STREAM),
61 mRecordingRequest(NULL)
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070062{
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070063 ATRACE_CALL();
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070064
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070065 mDevice = new Camera2Device(cameraId);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070066}
67
Eino-Ville Talvala3a609142012-07-31 14:36:26 -070068status_t Camera2Client::checkPid(const char* checkLocation) const {
69 int callingPid = getCallingPid();
70 if (callingPid == mClientPid) return NO_ERROR;
71
72 ALOGE("%s: attempt to use a locked camera from a different process"
73 " (old pid %d, new pid %d)", checkLocation, mClientPid, callingPid);
74 return PERMISSION_DENIED;
75}
76
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070077status_t Camera2Client::initialize(camera_module_t *module)
78{
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070079 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -070080 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070081 status_t res;
82
83 res = mDevice->initialize(module);
84 if (res != OK) {
85 ALOGE("%s: Camera %d: unable to initialize device: %s (%d)",
86 __FUNCTION__, mCameraId, strerror(-res), res);
87 return NO_INIT;
88 }
89
90 res = buildDefaultParameters();
91 if (res != OK) {
92 ALOGE("%s: Camera %d: unable to build defaults: %s (%d)",
93 __FUNCTION__, mCameraId, strerror(-res), res);
94 return NO_INIT;
95 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -070096
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070097 if (gLogLevel >= 1) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -070098 LockedParameters::Key k(mParameters);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070099 ALOGD("%s: Default parameters converted from camera %d:", __FUNCTION__,
100 mCameraId);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700101 ALOGD("%s", k.mParameters.paramsFlattened.string());
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700102 }
103
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700104 mState = STOPPED;
105
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700106 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700107}
108
109Camera2Client::~Camera2Client() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700110 ATRACE_CALL();
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700111 ALOGV("%s: Camera %d: Shutting down", __FUNCTION__, mCameraId);
112
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700113 mDestructionStarted = true;
114
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700115 // Rewrite mClientPid to allow shutdown by CameraService
116 mClientPid = getCallingPid();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700117 disconnect();
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -0700118
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700119}
120
121status_t Camera2Client::dump(int fd, const Vector<String16>& args) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700122 String8 result;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700123 result.appendFormat("Client2[%d] (%p) PID: %d, dump:\n",
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700124 mCameraId,
125 getCameraClient()->asBinder().get(),
126 mClientPid);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700127 result.append(" State: ");
128#define CASE_APPEND_ENUM(x) case x: result.append(#x "\n"); break;
129
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700130 const Parameters& p = mParameters.unsafeUnlock();
131
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700132 result.append(getStateName(mState));
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700133
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700134 result.append("\n Current parameters:\n");
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700135 result.appendFormat(" Preview size: %d x %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700136 p.previewWidth, p.previewHeight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700137 result.appendFormat(" Preview FPS range: %d - %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700138 p.previewFpsRange[0], p.previewFpsRange[1]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700139 result.appendFormat(" Preview HAL pixel format: 0x%x\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700140 p.previewFormat);
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700141 result.appendFormat(" Preview transform: %x\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700142 p.previewTransform);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700143 result.appendFormat(" Picture size: %d x %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700144 p.pictureWidth, p.pictureHeight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700145 result.appendFormat(" Jpeg thumbnail size: %d x %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700146 p.jpegThumbSize[0], p.jpegThumbSize[1]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700147 result.appendFormat(" Jpeg quality: %d, thumbnail quality: %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700148 p.jpegQuality, p.jpegThumbQuality);
149 result.appendFormat(" Jpeg rotation: %d\n", p.jpegRotation);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700150 result.appendFormat(" GPS tags %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700151 p.gpsEnabled ? "enabled" : "disabled");
152 if (p.gpsEnabled) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700153 result.appendFormat(" GPS lat x long x alt: %f x %f x %f\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700154 p.gpsCoordinates[0], p.gpsCoordinates[1],
155 p.gpsCoordinates[2]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700156 result.appendFormat(" GPS timestamp: %lld\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700157 p.gpsTimestamp);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700158 result.appendFormat(" GPS processing method: %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700159 p.gpsProcessingMethod.string());
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700160 }
161
162 result.append(" White balance mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700163 switch (p.wbMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700164 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_AUTO)
165 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_INCANDESCENT)
166 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_FLUORESCENT)
167 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_WARM_FLUORESCENT)
168 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_DAYLIGHT)
169 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT)
170 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_TWILIGHT)
171 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_SHADE)
172 default: result.append("UNKNOWN\n");
173 }
174
175 result.append(" Effect mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700176 switch (p.effectMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700177 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_OFF)
178 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_MONO)
179 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_NEGATIVE)
180 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_SOLARIZE)
181 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_SEPIA)
182 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_POSTERIZE)
183 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_WHITEBOARD)
184 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_BLACKBOARD)
185 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_AQUA)
186 default: result.append("UNKNOWN\n");
187 }
188
189 result.append(" Antibanding mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700190 switch (p.antibandingMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700191 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_AUTO)
192 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_OFF)
193 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_50HZ)
194 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_60HZ)
195 default: result.append("UNKNOWN\n");
196 }
197
198 result.append(" Scene mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700199 switch (p.sceneMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700200 case ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED:
201 result.append("AUTO\n"); break;
202 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_ACTION)
203 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_PORTRAIT)
204 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_LANDSCAPE)
205 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_NIGHT)
206 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT)
207 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_THEATRE)
208 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_BEACH)
209 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SNOW)
210 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SUNSET)
211 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO)
212 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_FIREWORKS)
213 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SPORTS)
214 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_PARTY)
215 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT)
216 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_BARCODE)
217 default: result.append("UNKNOWN\n");
218 }
219
220 result.append(" Flash mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700221 switch (p.flashMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700222 CASE_APPEND_ENUM(Parameters::FLASH_MODE_OFF)
223 CASE_APPEND_ENUM(Parameters::FLASH_MODE_AUTO)
224 CASE_APPEND_ENUM(Parameters::FLASH_MODE_ON)
225 CASE_APPEND_ENUM(Parameters::FLASH_MODE_TORCH)
226 CASE_APPEND_ENUM(Parameters::FLASH_MODE_RED_EYE)
227 CASE_APPEND_ENUM(Parameters::FLASH_MODE_INVALID)
228 default: result.append("UNKNOWN\n");
229 }
230
231 result.append(" Focus mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700232 switch (p.focusMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700233 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_AUTO)
234 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_MACRO)
235 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_CONTINUOUS_VIDEO)
236 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_CONTINUOUS_PICTURE)
237 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_EDOF)
238 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_INFINITY)
239 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_FIXED)
240 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_INVALID)
241 default: result.append("UNKNOWN\n");
242 }
243
244 result.append(" Focusing areas:\n");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700245 for (size_t i = 0; i < p.focusingAreas.size(); i++) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700246 result.appendFormat(" [ (%d, %d, %d, %d), weight %d ]\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700247 p.focusingAreas[i].left,
248 p.focusingAreas[i].top,
249 p.focusingAreas[i].right,
250 p.focusingAreas[i].bottom,
251 p.focusingAreas[i].weight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700252 }
253
254 result.appendFormat(" Exposure compensation index: %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700255 p.exposureCompensation);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700256
257 result.appendFormat(" AE lock %s, AWB lock %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700258 p.autoExposureLock ? "enabled" : "disabled",
259 p.autoWhiteBalanceLock ? "enabled" : "disabled" );
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700260
261 result.appendFormat(" Metering areas:\n");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700262 for (size_t i = 0; i < p.meteringAreas.size(); i++) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700263 result.appendFormat(" [ (%d, %d, %d, %d), weight %d ]\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700264 p.meteringAreas[i].left,
265 p.meteringAreas[i].top,
266 p.meteringAreas[i].right,
267 p.meteringAreas[i].bottom,
268 p.meteringAreas[i].weight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700269 }
270
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700271 result.appendFormat(" Zoom index: %d\n", p.zoom);
272 result.appendFormat(" Video size: %d x %d\n", p.videoWidth,
273 p.videoHeight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700274
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700275 result.appendFormat(" Recording hint is %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700276 p.recordingHint ? "set" : "not set");
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700277
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700278 result.appendFormat(" Video stabilization is %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700279 p.videoStabilization ? "enabled" : "disabled");
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700280
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700281 result.append(" Current streams:\n");
282 result.appendFormat(" Preview stream ID: %d\n", mPreviewStreamId);
283 result.appendFormat(" Capture stream ID: %d\n", mCaptureStreamId);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700284 result.appendFormat(" Recording stream ID: %d\n", mRecordingStreamId);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700285
286 result.append(" Current requests:\n");
287 if (mPreviewRequest != NULL) {
288 result.append(" Preview request:\n");
289 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700290 dump_indented_camera_metadata(mPreviewRequest, fd, 2, 6);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700291 } else {
292 result.append(" Preview request: undefined\n");
293 write(fd, result.string(), result.size());
294 }
295
296 if (mCaptureRequest != NULL) {
297 result = " Capture request:\n";
298 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700299 dump_indented_camera_metadata(mCaptureRequest, fd, 2, 6);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700300 } else {
301 result = " Capture request: undefined\n";
302 write(fd, result.string(), result.size());
303 }
304
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700305 if (mRecordingRequest != NULL) {
306 result = " Recording request:\n";
307 write(fd, result.string(), result.size());
308 dump_indented_camera_metadata(mRecordingRequest, fd, 2, 6);
309 } else {
310 result = " Recording request: undefined\n";
311 write(fd, result.string(), result.size());
312 }
313
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700314 result = " Device dump:\n";
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700315 write(fd, result.string(), result.size());
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700316
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700317 status_t res = mDevice->dump(fd, args);
318 if (res != OK) {
319 result = String8::format(" Error dumping device: %s (%d)",
320 strerror(-res), res);
321 write(fd, result.string(), result.size());
322 }
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700323
324#undef CASE_APPEND_ENUM
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700325 return NO_ERROR;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700326}
327
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700328const char* Camera2Client::getStateName(State state) {
329#define CASE_ENUM_TO_CHAR(x) case x: return(#x); break;
330 switch(state) {
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700331 CASE_ENUM_TO_CHAR(DISCONNECTED)
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700332 CASE_ENUM_TO_CHAR(STOPPED)
333 CASE_ENUM_TO_CHAR(WAITING_FOR_PREVIEW_WINDOW)
334 CASE_ENUM_TO_CHAR(PREVIEW)
335 CASE_ENUM_TO_CHAR(RECORD)
336 CASE_ENUM_TO_CHAR(STILL_CAPTURE)
337 CASE_ENUM_TO_CHAR(VIDEO_SNAPSHOT)
338 default:
339 return "Unknown state!";
340 break;
341 }
342#undef CASE_ENUM_TO_CHAR
343}
344
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700345// ICamera interface
346
347void Camera2Client::disconnect() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700348 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700349 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700350 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700351 status_t res;
352 if ( (res = checkPid(__FUNCTION__) ) != OK) return;
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700353
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700354 if (mDevice == 0) return;
355
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700356 stopPreviewLocked();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700357
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700358 mDevice->waitUntilDrained();
359
360 if (mPreviewStreamId != NO_STREAM) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700361 mDevice->deleteStream(mPreviewStreamId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700362 mPreviewStreamId = NO_STREAM;
363 }
364
365 if (mCaptureStreamId != NO_STREAM) {
366 mDevice->deleteStream(mCaptureStreamId);
367 mCaptureStreamId = NO_STREAM;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700368 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700369
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -0700370 if (mRecordingStreamId != NO_STREAM) {
371 mDevice->deleteStream(mRecordingStreamId);
372 mRecordingStreamId = NO_STREAM;
373 }
374
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700375 mDevice.clear();
376 mState = DISCONNECTED;
377
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700378 CameraService::Client::disconnect();
379}
380
381status_t Camera2Client::connect(const sp<ICameraClient>& client) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700382 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700383 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700384 Mutex::Autolock icl(mICameraLock);
385
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700386 if (mClientPid != 0 && getCallingPid() != mClientPid) {
387 ALOGE("%s: Camera %d: Connection attempt from pid %d; "
388 "current locked to pid %d", __FUNCTION__,
389 mCameraId, getCallingPid(), mClientPid);
390 return BAD_VALUE;
391 }
392
393 mClientPid = getCallingPid();
394 mCameraClient = client;
395
396 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700397}
398
399status_t Camera2Client::lock() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700400 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700401 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700402 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700403 ALOGV("%s: Camera %d: Lock call from pid %d; current client pid %d",
404 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700405
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700406 if (mClientPid == 0) {
407 mClientPid = getCallingPid();
408 return OK;
409 }
410
411 if (mClientPid != getCallingPid()) {
412 ALOGE("%s: Camera %d: Lock call from pid %d; currently locked to pid %d",
413 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
414 return EBUSY;
415 }
416
417 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700418}
419
420status_t Camera2Client::unlock() {
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: Unlock 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 // TODO: Check for uninterruptable conditions
428
429 if (mClientPid == getCallingPid()) {
430 mClientPid = 0;
431 mCameraClient.clear();
432 return OK;
433 }
434
435 ALOGE("%s: Camera %d: Unlock call from pid %d; currently locked to pid %d",
436 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
437 return EBUSY;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700438}
439
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700440status_t Camera2Client::setPreviewDisplay(
441 const sp<Surface>& surface) {
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 Talvala3a609142012-07-31 14:36:26 -0700445 status_t res;
446 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700447
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700448 sp<IBinder> binder;
449 sp<ANativeWindow> window;
450 if (surface != 0) {
451 binder = surface->asBinder();
452 window = surface;
453 }
454
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700455 return setPreviewWindowLocked(binder,window);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700456}
457
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700458status_t Camera2Client::setPreviewTexture(
459 const sp<ISurfaceTexture>& surfaceTexture) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700460 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700461 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700462 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700463 status_t res;
464 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700465
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700466 sp<IBinder> binder;
467 sp<ANativeWindow> window;
468 if (surfaceTexture != 0) {
469 binder = surfaceTexture->asBinder();
470 window = new SurfaceTextureClient(surfaceTexture);
471 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700472 return setPreviewWindowLocked(binder, window);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700473}
474
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700475status_t Camera2Client::setPreviewWindowLocked(const sp<IBinder>& binder,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700476 sp<ANativeWindow> window) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700477 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700478 status_t res;
479
480 if (binder == mPreviewSurface) {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700481 ALOGV("%s: Camera %d: New window is same as old window",
482 __FUNCTION__, mCameraId);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700483 return NO_ERROR;
484 }
485
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700486 switch (mState) {
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700487 case DISCONNECTED:
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700488 case RECORD:
489 case STILL_CAPTURE:
490 case VIDEO_SNAPSHOT:
491 ALOGE("%s: Camera %d: Cannot set preview display while in state %s",
492 __FUNCTION__, mCameraId, getStateName(mState));
493 return INVALID_OPERATION;
494 case STOPPED:
495 case WAITING_FOR_PREVIEW_WINDOW:
496 // OK
497 break;
498 case PREVIEW:
499 // Already running preview - need to stop and create a new stream
500 // TODO: Optimize this so that we don't wait for old stream to drain
501 // before spinning up new stream
502 mDevice->setStreamingRequest(NULL);
503 mState = WAITING_FOR_PREVIEW_WINDOW;
504 break;
505 }
506
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700507 if (mPreviewStreamId != NO_STREAM) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700508 res = mDevice->waitUntilDrained();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700509 if (res != OK) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700510 ALOGE("%s: Error waiting for preview to drain: %s (%d)",
511 __FUNCTION__, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700512 return res;
513 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700514 res = mDevice->deleteStream(mPreviewStreamId);
515 if (res != OK) {
516 ALOGE("%s: Unable to delete old preview stream: %s (%d)",
517 __FUNCTION__, strerror(-res), res);
518 return res;
519 }
520 mPreviewStreamId = NO_STREAM;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700521 }
522
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700523 mPreviewSurface = binder;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700524 mPreviewWindow = window;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700525
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700526 if (mState == WAITING_FOR_PREVIEW_WINDOW) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700527 return startPreviewLocked();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700528 }
529
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700530 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700531}
532
533void Camera2Client::setPreviewCallbackFlag(int flag) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700534 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700535 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700536 status_t res;
537 if ( (res = checkPid(__FUNCTION__) ) != OK) return;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700538}
539
540status_t Camera2Client::startPreview() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700541 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700542 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700543 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700544 status_t res;
545 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700546 return startPreviewLocked();
547}
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700548
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700549status_t Camera2Client::startPreviewLocked() {
550 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700551 status_t res;
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700552 if (mState >= PREVIEW) {
553 ALOGE("%s: Can't start preview in state %s",
554 __FUNCTION__, getStateName(mState));
555 return INVALID_OPERATION;
556 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700557
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700558 if (mPreviewWindow == 0) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700559 mState = WAITING_FOR_PREVIEW_WINDOW;
560 return OK;
561 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700562 mState = STOPPED;
563
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700564 LockedParameters::Key k(mParameters);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700565
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700566 res = updatePreviewStream(k.mParameters);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700567 if (res != OK) {
568 ALOGE("%s: Camera %d: Unable to update preview stream: %s (%d)",
569 __FUNCTION__, mCameraId, strerror(-res), res);
570 return res;
571 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700572
573 if (mPreviewRequest == NULL) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700574 res = updatePreviewRequest(k.mParameters);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700575 if (res != OK) {
576 ALOGE("%s: Camera %d: Unable to create preview request: %s (%d)",
577 __FUNCTION__, mCameraId, strerror(-res), res);
578 return res;
579 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700580 }
581
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700582 res = updateEntry(mPreviewRequest,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700583 ANDROID_REQUEST_OUTPUT_STREAMS,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700584 &mPreviewStreamId, 1);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700585 if (res != OK) {
586 ALOGE("%s: Camera %d: Unable to set up preview request: %s (%d)",
587 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700588 return res;
589 }
590 res = sort_camera_metadata(mPreviewRequest);
591 if (res != OK) {
592 ALOGE("%s: Camera %d: Error sorting preview request: %s (%d)",
593 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700594 return res;
595 }
596
597 res = mDevice->setStreamingRequest(mPreviewRequest);
598 if (res != OK) {
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700599 ALOGE("%s: Camera %d: Unable to set preview request to start preview: "
600 "%s (%d)",
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700601 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700602 return res;
603 }
604 mState = PREVIEW;
605
606 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700607}
608
609void Camera2Client::stopPreview() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700610 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700611 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700612 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700613 status_t res;
614 if ( (res = checkPid(__FUNCTION__) ) != OK) return;
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700615 stopPreviewLocked();
616}
617
618void Camera2Client::stopPreviewLocked() {
619 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700620 switch (mState) {
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700621 case DISCONNECTED:
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700622 ALOGE("%s: Camera %d: Call before initialized",
623 __FUNCTION__, mCameraId);
624 break;
625 case STOPPED:
626 break;
627 case STILL_CAPTURE:
628 ALOGE("%s: Camera %d: Cannot stop preview during still capture.",
629 __FUNCTION__, mCameraId);
630 break;
631 case RECORD:
632 // TODO: Handle record stop here
633 case PREVIEW:
634 mDevice->setStreamingRequest(NULL);
Eino-Ville Talvala22671062012-07-20 18:30:37 -0700635 mDevice->waitUntilDrained();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700636 case WAITING_FOR_PREVIEW_WINDOW:
637 mState = STOPPED;
638 break;
639 default:
640 ALOGE("%s: Camera %d: Unknown state %d", __FUNCTION__, mCameraId,
641 mState);
642 }
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700643}
644
645bool Camera2Client::previewEnabled() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700646 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700647 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700648 status_t res;
649 if ( (res = checkPid(__FUNCTION__) ) != OK) return false;
650
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700651 return mState == PREVIEW;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700652}
653
654status_t Camera2Client::storeMetaDataInBuffers(bool enabled) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700655 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700656 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700657 status_t res;
658 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
659
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700660 switch (mState) {
661 case RECORD:
662 case VIDEO_SNAPSHOT:
663 ALOGE("%s: Camera %d: Can't be called in state %s",
664 __FUNCTION__, mCameraId, getStateName(mState));
665 return INVALID_OPERATION;
666 default:
667 // OK
668 break;
669 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700670 LockedParameters::Key k(mParameters);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700671
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700672 k.mParameters.storeMetadataInBuffers = enabled;
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700673
674 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700675}
676
677status_t Camera2Client::startRecording() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700678 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700679 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700680 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700681 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700682 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
683
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700684 switch (mState) {
685 case STOPPED:
686 res = startPreviewLocked();
687 if (res != OK) return res;
688 break;
689 case PREVIEW:
690 // Ready to go
691 break;
692 case RECORD:
693 case VIDEO_SNAPSHOT:
694 // OK to call this when recording is already on
695 return OK;
696 break;
697 default:
698 ALOGE("%s: Camera %d: Can't start recording in state %s",
699 __FUNCTION__, mCameraId, getStateName(mState));
700 return INVALID_OPERATION;
701 };
702
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700703 LockedParameters::Key k(mParameters);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700704
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700705 if (!k.mParameters.storeMetadataInBuffers) {
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700706 ALOGE("%s: Camera %d: Recording only supported in metadata mode, but "
707 "non-metadata recording mode requested!", __FUNCTION__,
708 mCameraId);
709 return INVALID_OPERATION;
710 }
711
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700712 res = updateRecordingStream(k.mParameters);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700713 if (res != OK) {
714 ALOGE("%s: Camera %d: Unable to update recording stream: %s (%d)",
715 __FUNCTION__, mCameraId, strerror(-res), res);
716 return res;
717 }
718
719 if (mRecordingRequest == NULL) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700720 res = updateRecordingRequest(k.mParameters);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700721 if (res != OK) {
722 ALOGE("%s: Camera %d: Unable to create recording request: %s (%d)",
723 __FUNCTION__, mCameraId, strerror(-res), res);
724 return res;
725 }
726 }
727
728 uint8_t outputStreams[2] = { mPreviewStreamId, mRecordingStreamId };
729 res = updateEntry(mRecordingRequest,
730 ANDROID_REQUEST_OUTPUT_STREAMS,
731 outputStreams, 2);
732 if (res != OK) {
733 ALOGE("%s: Camera %d: Unable to set up recording request: %s (%d)",
734 __FUNCTION__, mCameraId, strerror(-res), res);
735 return res;
736 }
737 res = sort_camera_metadata(mRecordingRequest);
738 if (res != OK) {
739 ALOGE("%s: Camera %d: Error sorting recording request: %s (%d)",
740 __FUNCTION__, mCameraId, strerror(-res), res);
741 return res;
742 }
743
744 res = mDevice->setStreamingRequest(mRecordingRequest);
745 if (res != OK) {
746 ALOGE("%s: Camera %d: Unable to set recording request to start "
747 "recording: %s (%d)", __FUNCTION__, mCameraId,
748 strerror(-res), res);
749 return res;
750 }
751 mState = RECORD;
752
753 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700754}
755
756void Camera2Client::stopRecording() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700757 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700758 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700759 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700760 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700761 if ( (res = checkPid(__FUNCTION__) ) != OK) return;
762
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700763 switch (mState) {
764 case RECORD:
765 // OK to stop
766 break;
767 case STOPPED:
768 case PREVIEW:
769 case STILL_CAPTURE:
770 case VIDEO_SNAPSHOT:
771 default:
772 ALOGE("%s: Camera %d: Can't stop recording in state %s",
773 __FUNCTION__, mCameraId, getStateName(mState));
774 return;
775 };
776
777 // Back to preview. Since record can only be reached through preview,
778 // all preview stream setup should be up to date.
779 res = mDevice->setStreamingRequest(mPreviewRequest);
780 if (res != OK) {
781 ALOGE("%s: Camera %d: Unable to switch back to preview request: "
782 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
783 return;
784 }
785
786 // TODO: Should recording heap be freed? Can't do it yet since requests
787 // could still be in flight.
788
789 mState = PREVIEW;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700790}
791
792bool Camera2Client::recordingEnabled() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700793 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700794 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700795 if ( checkPid(__FUNCTION__) != OK) return false;
796
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700797 return (mState == RECORD || mState == VIDEO_SNAPSHOT);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700798}
799
800void Camera2Client::releaseRecordingFrame(const sp<IMemory>& mem) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700801 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700802 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700803 status_t res;
804 if ( checkPid(__FUNCTION__) != OK) return;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700805 // Make sure this is for the current heap
806 ssize_t offset;
807 size_t size;
808 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
809 if (heap->getHeapID() != mRecordingHeap->mHeap->getHeapID()) {
810 ALOGW("%s: Camera %d: Mismatched heap ID, ignoring release "
811 "(got %x, expected %x)", __FUNCTION__, mCameraId,
812 heap->getHeapID(), mRecordingHeap->mHeap->getHeapID());
813 return;
814 }
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700815 uint8_t *data = (uint8_t*)heap->getBase() + offset;
816 uint32_t type = *(uint32_t*)data;
817 if (type != kMetadataBufferTypeGrallocSource) {
818 ALOGE("%s: Camera %d: Recording frame type invalid (got %x, expected %x)",
819 __FUNCTION__, mCameraId, type, kMetadataBufferTypeGrallocSource);
820 return;
821 }
822 buffer_handle_t imgBuffer = *(buffer_handle_t*)(data + 4);
823 ALOGV("%s: Camera %d: Freeing buffer_handle_t %p", __FUNCTION__, mCameraId,
Eino-Ville Talvala803cbf62012-07-25 15:23:36 -0700824 imgBuffer);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700825 res = mRecordingConsumer->freeBuffer(imgBuffer);
826 if (res != OK) {
827 ALOGE("%s: Camera %d: Unable to free recording frame (buffer_handle_t: %p):"
828 "%s (%d)",
829 __FUNCTION__, mCameraId, imgBuffer, strerror(-res), res);
830 return;
831 }
832
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700833 mRecordingHeapFree++;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700834}
835
836status_t Camera2Client::autoFocus() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700837 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700838 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700839 status_t res;
840 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
841
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700842 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700843}
844
845status_t Camera2Client::cancelAutoFocus() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700846 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700847 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700848 status_t res;
849 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
850
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700851 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700852}
853
854status_t Camera2Client::takePicture(int msgType) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700855 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700856 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700857 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700858 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700859
860 switch (mState) {
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700861 case DISCONNECTED:
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700862 case STOPPED:
863 case WAITING_FOR_PREVIEW_WINDOW:
864 ALOGE("%s: Camera %d: Cannot take picture without preview enabled",
865 __FUNCTION__, mCameraId);
866 return INVALID_OPERATION;
867 case PREVIEW:
868 case RECORD:
869 // Good to go for takePicture
870 break;
871 case STILL_CAPTURE:
872 case VIDEO_SNAPSHOT:
873 ALOGE("%s: Camera %d: Already taking a picture",
874 __FUNCTION__, mCameraId);
875 return INVALID_OPERATION;
876 }
877
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700878 LockedParameters::Key k(mParameters);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700879
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700880 res = updateCaptureStream(k.mParameters);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700881 if (res != OK) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700882 ALOGE("%s: Camera %d: Can't set up still image stream: %s (%d)",
883 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700884 return res;
885 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700886
887 if (mCaptureRequest == NULL) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700888 res = updateCaptureRequest(k.mParameters);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700889 if (res != OK) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700890 ALOGE("%s: Camera %d: Can't create still image capture request: "
891 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700892 return res;
893 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700894 }
895
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700896 camera_metadata_entry_t outputStreams;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700897 if (mState == PREVIEW) {
898 uint8_t streamIds[2] = { mPreviewStreamId, mCaptureStreamId };
899 res = updateEntry(mCaptureRequest, ANDROID_REQUEST_OUTPUT_STREAMS,
900 &streamIds, 2);
901 } else if (mState == RECORD) {
902 uint8_t streamIds[3] = { mPreviewStreamId, mRecordingStreamId,
903 mCaptureStreamId };
904 res = updateEntry(mCaptureRequest, ANDROID_REQUEST_OUTPUT_STREAMS,
905 &streamIds, 3);
906 }
907
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700908 if (res != OK) {
909 ALOGE("%s: Camera %d: Unable to set up still image capture request: "
910 "%s (%d)",
911 __FUNCTION__, mCameraId, strerror(-res), res);
912 return res;
913 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700914 res = sort_camera_metadata(mCaptureRequest);
915 if (res != OK) {
916 ALOGE("%s: Camera %d: Unable to sort capture request: %s (%d)",
917 __FUNCTION__, mCameraId, strerror(-res), res);
918 return res;
919 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700920
921 camera_metadata_t *captureCopy = clone_camera_metadata(mCaptureRequest);
922 if (captureCopy == NULL) {
923 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device",
924 __FUNCTION__, mCameraId);
925 return NO_MEMORY;
926 }
927
928 if (mState == PREVIEW) {
929 res = mDevice->setStreamingRequest(NULL);
930 if (res != OK) {
931 ALOGE("%s: Camera %d: Unable to stop preview for still capture: "
932 "%s (%d)",
933 __FUNCTION__, mCameraId, strerror(-res), res);
934 return res;
935 }
936 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700937 // TODO: Capture should be atomic with setStreamingRequest here
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700938 res = mDevice->capture(captureCopy);
939 if (res != OK) {
940 ALOGE("%s: Camera %d: Unable to submit still image capture request: "
941 "%s (%d)",
942 __FUNCTION__, mCameraId, strerror(-res), res);
943 return res;
944 }
945
946 switch (mState) {
947 case PREVIEW:
948 mState = STILL_CAPTURE;
949 break;
950 case RECORD:
951 mState = VIDEO_SNAPSHOT;
952 break;
953 default:
954 ALOGE("%s: Camera %d: Unknown state for still capture!",
955 __FUNCTION__, mCameraId);
956 return INVALID_OPERATION;
957 }
958
959 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700960}
961
962status_t Camera2Client::setParameters(const String8& params) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700963 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700964 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700965 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700966 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700967 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
968
969 LockedParameters::Key k(mParameters);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700970
971 CameraParameters newParams(params);
972
973 // TODO: Currently ignoring any changes to supposedly read-only
974 // parameters such as supported preview sizes, etc. Should probably
975 // produce an error if they're changed.
976
977 /** Extract and verify new parameters */
978
979 size_t i;
980
981 // PREVIEW_SIZE
982 int previewWidth, previewHeight;
983 newParams.getPreviewSize(&previewWidth, &previewHeight);
984
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700985 if (previewWidth != k.mParameters.previewWidth ||
986 previewHeight != k.mParameters.previewHeight) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700987 if (mState >= PREVIEW) {
988 ALOGE("%s: Preview size cannot be updated when preview "
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700989 "is active! (Currently %d x %d, requested %d x %d",
990 __FUNCTION__,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700991 k.mParameters.previewWidth, k.mParameters.previewHeight,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700992 previewWidth, previewHeight);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700993 return BAD_VALUE;
994 }
995 camera_metadata_entry_t availablePreviewSizes =
996 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
997 for (i = 0; i < availablePreviewSizes.count; i += 2 ) {
998 if (availablePreviewSizes.data.i32[i] == previewWidth &&
999 availablePreviewSizes.data.i32[i+1] == previewHeight) break;
1000 }
1001 if (i == availablePreviewSizes.count) {
1002 ALOGE("%s: Requested preview size %d x %d is not supported",
1003 __FUNCTION__, previewWidth, previewHeight);
1004 return BAD_VALUE;
1005 }
1006 }
1007
1008 // PREVIEW_FPS_RANGE
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001009 int previewFpsRange[2];
1010 int previewFps = 0;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001011 bool fpsRangeChanged = false;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001012 newParams.getPreviewFpsRange(&previewFpsRange[0], &previewFpsRange[1]);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001013 if (previewFpsRange[0] != k.mParameters.previewFpsRange[0] ||
1014 previewFpsRange[1] != k.mParameters.previewFpsRange[1]) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001015 fpsRangeChanged = true;
1016 camera_metadata_entry_t availablePreviewFpsRanges =
1017 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
1018 for (i = 0; i < availablePreviewFpsRanges.count; i += 2) {
1019 if ((availablePreviewFpsRanges.data.i32[i] ==
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001020 previewFpsRange[0]) &&
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001021 (availablePreviewFpsRanges.data.i32[i+1] ==
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001022 previewFpsRange[1]) ) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001023 break;
1024 }
1025 }
1026 if (i == availablePreviewFpsRanges.count) {
1027 ALOGE("%s: Requested preview FPS range %d - %d is not supported",
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001028 __FUNCTION__, previewFpsRange[0], previewFpsRange[1]);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001029 return BAD_VALUE;
1030 }
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001031 previewFps = previewFpsRange[0];
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001032 }
1033
1034 // PREVIEW_FORMAT
1035 int previewFormat = formatStringToEnum(newParams.getPreviewFormat());
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001036 if (previewFormat != k.mParameters.previewFormat) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001037 if (mState >= PREVIEW) {
1038 ALOGE("%s: Preview format cannot be updated when preview "
1039 "is active!", __FUNCTION__);
1040 return BAD_VALUE;
1041 }
1042 camera_metadata_entry_t availableFormats =
1043 staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
1044 for (i = 0; i < availableFormats.count; i++) {
1045 if (availableFormats.data.i32[i] == previewFormat) break;
1046 }
1047 if (i == availableFormats.count) {
1048 ALOGE("%s: Requested preview format %s (0x%x) is not supported",
1049 __FUNCTION__, newParams.getPreviewFormat(), previewFormat);
1050 return BAD_VALUE;
1051 }
1052 }
1053
1054 // PREVIEW_FRAME_RATE
1055 // Deprecated, only use if the preview fps range is unchanged this time.
1056 // The single-value FPS is the same as the minimum of the range.
1057 if (!fpsRangeChanged) {
1058 previewFps = newParams.getPreviewFrameRate();
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001059 if (previewFps != k.mParameters.previewFps) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001060 camera_metadata_entry_t availableFrameRates =
1061 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
1062 for (i = 0; i < availableFrameRates.count; i+=2) {
1063 if (availableFrameRates.data.i32[i] == previewFps) break;
1064 }
1065 if (i == availableFrameRates.count) {
1066 ALOGE("%s: Requested preview frame rate %d is not supported",
1067 __FUNCTION__, previewFps);
1068 return BAD_VALUE;
1069 }
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001070 previewFpsRange[0] = availableFrameRates.data.i32[i];
1071 previewFpsRange[1] = availableFrameRates.data.i32[i+1];
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001072 }
1073 }
1074
1075 // PICTURE_SIZE
1076 int pictureWidth, pictureHeight;
1077 newParams.getPictureSize(&pictureWidth, &pictureHeight);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001078 if (pictureWidth == k.mParameters.pictureWidth ||
1079 pictureHeight == k.mParameters.pictureHeight) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001080 camera_metadata_entry_t availablePictureSizes =
1081 staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES);
1082 for (i = 0; i < availablePictureSizes.count; i+=2) {
1083 if (availablePictureSizes.data.i32[i] == pictureWidth &&
1084 availablePictureSizes.data.i32[i+1] == pictureHeight) break;
1085 }
1086 if (i == availablePictureSizes.count) {
1087 ALOGE("%s: Requested picture size %d x %d is not supported",
1088 __FUNCTION__, pictureWidth, pictureHeight);
1089 return BAD_VALUE;
1090 }
1091 }
1092
1093 // JPEG_THUMBNAIL_WIDTH/HEIGHT
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001094 int jpegThumbSize[2];
1095 jpegThumbSize[0] =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001096 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001097 jpegThumbSize[1] =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001098 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001099 if (jpegThumbSize[0] != k.mParameters.jpegThumbSize[0] ||
1100 jpegThumbSize[1] != k.mParameters.jpegThumbSize[1]) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001101 camera_metadata_entry_t availableJpegThumbSizes =
1102 staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES);
1103 for (i = 0; i < availableJpegThumbSizes.count; i+=2) {
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001104 if (availableJpegThumbSizes.data.i32[i] == jpegThumbSize[0] &&
1105 availableJpegThumbSizes.data.i32[i+1] == jpegThumbSize[1]) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001106 break;
1107 }
1108 }
1109 if (i == availableJpegThumbSizes.count) {
1110 ALOGE("%s: Requested JPEG thumbnail size %d x %d is not supported",
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001111 __FUNCTION__, jpegThumbSize[0], jpegThumbSize[1]);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001112 return BAD_VALUE;
1113 }
1114 }
1115
1116 // JPEG_THUMBNAIL_QUALITY
1117 int jpegThumbQuality =
1118 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
1119 if (jpegThumbQuality < 0 || jpegThumbQuality > 100) {
1120 ALOGE("%s: Requested JPEG thumbnail quality %d is not supported",
1121 __FUNCTION__, jpegThumbQuality);
1122 return BAD_VALUE;
1123 }
1124
1125 // JPEG_QUALITY
1126 int jpegQuality =
1127 newParams.getInt(CameraParameters::KEY_JPEG_QUALITY);
1128 if (jpegQuality < 0 || jpegQuality > 100) {
1129 ALOGE("%s: Requested JPEG quality %d is not supported",
1130 __FUNCTION__, jpegQuality);
1131 return BAD_VALUE;
1132 }
1133
1134 // ROTATION
1135 int jpegRotation =
1136 newParams.getInt(CameraParameters::KEY_ROTATION);
1137 if (jpegRotation != 0 &&
1138 jpegRotation != 90 &&
1139 jpegRotation != 180 &&
1140 jpegRotation != 270) {
1141 ALOGE("%s: Requested picture rotation angle %d is not supported",
1142 __FUNCTION__, jpegRotation);
1143 return BAD_VALUE;
1144 }
1145
1146 // GPS
1147 bool gpsEnabled = false;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001148 double gpsCoordinates[3] = {0,0,0};
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001149 int64_t gpsTimestamp = 0;
1150 String8 gpsProcessingMethod;
1151 const char *gpsLatStr =
1152 newParams.get(CameraParameters::KEY_GPS_LATITUDE);
1153 if (gpsLatStr != NULL) {
1154 const char *gpsLongStr =
1155 newParams.get(CameraParameters::KEY_GPS_LONGITUDE);
1156 const char *gpsAltitudeStr =
1157 newParams.get(CameraParameters::KEY_GPS_ALTITUDE);
1158 const char *gpsTimeStr =
1159 newParams.get(CameraParameters::KEY_GPS_TIMESTAMP);
1160 const char *gpsProcMethodStr =
1161 newParams.get(CameraParameters::KEY_GPS_PROCESSING_METHOD);
1162 if (gpsLongStr == NULL ||
1163 gpsAltitudeStr == NULL ||
1164 gpsTimeStr == NULL ||
1165 gpsProcMethodStr == NULL) {
1166 ALOGE("%s: Incomplete set of GPS parameters provided",
1167 __FUNCTION__);
1168 return BAD_VALUE;
1169 }
1170 char *endPtr;
1171 errno = 0;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001172 gpsCoordinates[0] = strtod(gpsLatStr, &endPtr);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001173 if (errno || endPtr == gpsLatStr) {
1174 ALOGE("%s: Malformed GPS latitude: %s", __FUNCTION__, gpsLatStr);
1175 return BAD_VALUE;
1176 }
1177 errno = 0;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001178 gpsCoordinates[1] = strtod(gpsLongStr, &endPtr);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001179 if (errno || endPtr == gpsLongStr) {
1180 ALOGE("%s: Malformed GPS longitude: %s", __FUNCTION__, gpsLongStr);
1181 return BAD_VALUE;
1182 }
1183 errno = 0;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001184 gpsCoordinates[2] = strtod(gpsAltitudeStr, &endPtr);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001185 if (errno || endPtr == gpsAltitudeStr) {
1186 ALOGE("%s: Malformed GPS altitude: %s", __FUNCTION__,
1187 gpsAltitudeStr);
1188 return BAD_VALUE;
1189 }
1190 errno = 0;
1191 gpsTimestamp = strtoll(gpsTimeStr, &endPtr, 10);
1192 if (errno || endPtr == gpsTimeStr) {
1193 ALOGE("%s: Malformed GPS timestamp: %s", __FUNCTION__, gpsTimeStr);
1194 return BAD_VALUE;
1195 }
1196 gpsProcessingMethod = gpsProcMethodStr;
1197
1198 gpsEnabled = true;
1199 }
1200
1201 // WHITE_BALANCE
1202 int wbMode = wbModeStringToEnum(
1203 newParams.get(CameraParameters::KEY_WHITE_BALANCE) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001204 if (wbMode != k.mParameters.wbMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001205 camera_metadata_entry_t availableWbModes =
1206 staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
1207 for (i = 0; i < availableWbModes.count; i++) {
1208 if (wbMode == availableWbModes.data.u8[i]) break;
1209 }
1210 if (i == availableWbModes.count) {
1211 ALOGE("%s: Requested white balance mode %s is not supported",
1212 __FUNCTION__,
1213 newParams.get(CameraParameters::KEY_WHITE_BALANCE));
1214 return BAD_VALUE;
1215 }
1216 }
1217
1218 // EFFECT
1219 int effectMode = effectModeStringToEnum(
1220 newParams.get(CameraParameters::KEY_EFFECT) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001221 if (effectMode != k.mParameters.effectMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001222 camera_metadata_entry_t availableEffectModes =
1223 staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
1224 for (i = 0; i < availableEffectModes.count; i++) {
1225 if (effectMode == availableEffectModes.data.u8[i]) break;
1226 }
1227 if (i == availableEffectModes.count) {
1228 ALOGE("%s: Requested effect mode \"%s\" is not supported",
1229 __FUNCTION__,
1230 newParams.get(CameraParameters::KEY_EFFECT) );
1231 return BAD_VALUE;
1232 }
1233 }
1234
1235 // ANTIBANDING
1236 int antibandingMode = abModeStringToEnum(
1237 newParams.get(CameraParameters::KEY_ANTIBANDING) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001238 if (antibandingMode != k.mParameters.antibandingMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001239 camera_metadata_entry_t availableAbModes =
1240 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
1241 for (i = 0; i < availableAbModes.count; i++) {
1242 if (antibandingMode == availableAbModes.data.u8[i]) break;
1243 }
1244 if (i == availableAbModes.count) {
1245 ALOGE("%s: Requested antibanding mode \"%s\" is not supported",
1246 __FUNCTION__,
1247 newParams.get(CameraParameters::KEY_ANTIBANDING));
1248 return BAD_VALUE;
1249 }
1250 }
1251
1252 // SCENE_MODE
1253 int sceneMode = sceneModeStringToEnum(
1254 newParams.get(CameraParameters::KEY_SCENE_MODE) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001255 if (sceneMode != k.mParameters.sceneMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001256 camera_metadata_entry_t availableSceneModes =
1257 staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
1258 for (i = 0; i < availableSceneModes.count; i++) {
1259 if (sceneMode == availableSceneModes.data.u8[i]) break;
1260 }
1261 if (i == availableSceneModes.count) {
1262 ALOGE("%s: Requested scene mode \"%s\" is not supported",
1263 __FUNCTION__,
1264 newParams.get(CameraParameters::KEY_SCENE_MODE));
1265 return BAD_VALUE;
1266 }
1267 }
1268
1269 // FLASH_MODE
1270 Parameters::flashMode_t flashMode = flashModeStringToEnum(
1271 newParams.get(CameraParameters::KEY_FLASH_MODE) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001272 if (flashMode != k.mParameters.flashMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001273 camera_metadata_entry_t flashAvailable =
1274 staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
1275 if (!flashAvailable.data.u8[0] &&
1276 flashMode != Parameters::FLASH_MODE_OFF) {
1277 ALOGE("%s: Requested flash mode \"%s\" is not supported: "
1278 "No flash on device", __FUNCTION__,
1279 newParams.get(CameraParameters::KEY_FLASH_MODE));
1280 return BAD_VALUE;
1281 } else if (flashMode == Parameters::FLASH_MODE_RED_EYE) {
1282 camera_metadata_entry_t availableAeModes =
1283 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
1284 for (i = 0; i < availableAeModes.count; i++) {
1285 if (flashMode == availableAeModes.data.u8[i]) break;
1286 }
1287 if (i == availableAeModes.count) {
1288 ALOGE("%s: Requested flash mode \"%s\" is not supported",
1289 __FUNCTION__,
1290 newParams.get(CameraParameters::KEY_FLASH_MODE));
1291 return BAD_VALUE;
1292 }
1293 } else if (flashMode == -1) {
1294 ALOGE("%s: Requested flash mode \"%s\" is unknown",
1295 __FUNCTION__,
1296 newParams.get(CameraParameters::KEY_FLASH_MODE));
1297 return BAD_VALUE;
1298 }
1299 }
1300
1301 // FOCUS_MODE
1302 Parameters::focusMode_t focusMode = focusModeStringToEnum(
1303 newParams.get(CameraParameters::KEY_FOCUS_MODE));
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001304 if (focusMode != k.mParameters.focusMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001305 if (focusMode != Parameters::FOCUS_MODE_FIXED) {
1306 camera_metadata_entry_t minFocusDistance =
1307 staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE);
1308 if (minFocusDistance.data.f[0] == 0) {
1309 ALOGE("%s: Requested focus mode \"%s\" is not available: "
1310 "fixed focus lens",
1311 __FUNCTION__,
1312 newParams.get(CameraParameters::KEY_FOCUS_MODE));
1313 return BAD_VALUE;
1314 } else if (focusMode != Parameters::FOCUS_MODE_INFINITY) {
1315 camera_metadata_entry_t availableFocusModes =
1316 staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
1317 for (i = 0; i < availableFocusModes.count; i++) {
1318 if (focusMode == availableFocusModes.data.u8[i]) break;
1319 }
1320 if (i == availableFocusModes.count) {
1321 ALOGE("%s: Requested focus mode \"%s\" is not supported",
1322 __FUNCTION__,
1323 newParams.get(CameraParameters::KEY_FOCUS_MODE));
1324 return BAD_VALUE;
1325 }
1326 }
1327 }
1328 }
1329
1330 // FOCUS_AREAS
1331 Vector<Parameters::Area> focusingAreas;
1332 res = parseAreas(newParams.get(CameraParameters::KEY_FOCUS_AREAS),
1333 &focusingAreas);
1334 size_t max3aRegions =
1335 (size_t)staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1).data.i32[0];
1336 if (res == OK) res = validateAreas(focusingAreas, max3aRegions);
1337 if (res != OK) {
1338 ALOGE("%s: Requested focus areas are malformed: %s",
1339 __FUNCTION__, newParams.get(CameraParameters::KEY_FOCUS_AREAS));
1340 return BAD_VALUE;
1341 }
1342
1343 // EXPOSURE_COMPENSATION
1344 int exposureCompensation =
1345 newParams.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION);
1346 camera_metadata_entry_t exposureCompensationRange =
1347 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE);
1348 if (exposureCompensation < exposureCompensationRange.data.i32[0] ||
1349 exposureCompensation > exposureCompensationRange.data.i32[1]) {
1350 ALOGE("%s: Requested exposure compensation index is out of bounds: %d",
1351 __FUNCTION__, exposureCompensation);
1352 return BAD_VALUE;
1353 }
1354
1355 // AUTO_EXPOSURE_LOCK (always supported)
1356 bool autoExposureLock = boolFromString(
1357 newParams.get(CameraParameters::KEY_AUTO_EXPOSURE_LOCK));
1358
1359 // AUTO_WHITEBALANCE_LOCK (always supported)
1360 bool autoWhiteBalanceLock = boolFromString(
1361 newParams.get(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK));
1362
1363 // METERING_AREAS
1364 Vector<Parameters::Area> meteringAreas;
1365 res = parseAreas(newParams.get(CameraParameters::KEY_METERING_AREAS),
1366 &meteringAreas);
1367 if (res == OK) res = validateAreas(focusingAreas, max3aRegions);
1368 if (res != OK) {
1369 ALOGE("%s: Requested metering areas are malformed: %s",
1370 __FUNCTION__,
1371 newParams.get(CameraParameters::KEY_METERING_AREAS));
1372 return BAD_VALUE;
1373 }
1374
1375 // ZOOM
1376 int zoom = newParams.getInt(CameraParameters::KEY_ZOOM);
1377 if (zoom < 0 || zoom > (int)NUM_ZOOM_STEPS) {
1378 ALOGE("%s: Requested zoom level %d is not supported",
1379 __FUNCTION__, zoom);
1380 return BAD_VALUE;
1381 }
1382
1383 // VIDEO_SIZE
1384 int videoWidth, videoHeight;
1385 newParams.getVideoSize(&videoWidth, &videoHeight);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001386 if (videoWidth != k.mParameters.videoWidth ||
1387 videoHeight != k.mParameters.videoHeight) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001388 if (mState == RECORD) {
1389 ALOGE("%s: Video size cannot be updated when recording is active!",
1390 __FUNCTION__);
1391 return BAD_VALUE;
1392 }
1393 camera_metadata_entry_t availableVideoSizes =
1394 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
1395 for (i = 0; i < availableVideoSizes.count; i += 2 ) {
1396 if (availableVideoSizes.data.i32[i] == videoWidth &&
1397 availableVideoSizes.data.i32[i+1] == videoHeight) break;
1398 }
1399 if (i == availableVideoSizes.count) {
1400 ALOGE("%s: Requested video size %d x %d is not supported",
1401 __FUNCTION__, videoWidth, videoHeight);
1402 return BAD_VALUE;
1403 }
1404 }
1405
1406 // RECORDING_HINT (always supported)
1407 bool recordingHint = boolFromString(
1408 newParams.get(CameraParameters::KEY_RECORDING_HINT) );
1409
1410 // VIDEO_STABILIZATION
1411 bool videoStabilization = boolFromString(
1412 newParams.get(CameraParameters::KEY_VIDEO_STABILIZATION) );
1413 camera_metadata_entry_t availableVideoStabilizationModes =
1414 staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
1415 if (videoStabilization && availableVideoStabilizationModes.count == 1) {
1416 ALOGE("%s: Video stabilization not supported", __FUNCTION__);
1417 }
1418
1419 /** Update internal parameters */
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001420
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001421 k.mParameters.previewWidth = previewWidth;
1422 k.mParameters.previewHeight = previewHeight;
1423 k.mParameters.previewFpsRange[0] = previewFpsRange[0];
1424 k.mParameters.previewFpsRange[1] = previewFpsRange[1];
1425 k.mParameters.previewFps = previewFps;
1426 k.mParameters.previewFormat = previewFormat;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001427
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001428 k.mParameters.pictureWidth = pictureWidth;
1429 k.mParameters.pictureHeight = pictureHeight;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001430
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001431 k.mParameters.jpegThumbSize[0] = jpegThumbSize[0];
1432 k.mParameters.jpegThumbSize[1] = jpegThumbSize[1];
1433 k.mParameters.jpegQuality = jpegQuality;
1434 k.mParameters.jpegThumbQuality = jpegThumbQuality;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001435
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001436 k.mParameters.gpsEnabled = gpsEnabled;
1437 k.mParameters.gpsCoordinates[0] = gpsCoordinates[0];
1438 k.mParameters.gpsCoordinates[1] = gpsCoordinates[1];
1439 k.mParameters.gpsCoordinates[2] = gpsCoordinates[2];
1440 k.mParameters.gpsTimestamp = gpsTimestamp;
1441 k.mParameters.gpsProcessingMethod = gpsProcessingMethod;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001442
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001443 k.mParameters.wbMode = wbMode;
1444 k.mParameters.effectMode = effectMode;
1445 k.mParameters.antibandingMode = antibandingMode;
1446 k.mParameters.sceneMode = sceneMode;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001447
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001448 k.mParameters.flashMode = flashMode;
1449 k.mParameters.focusMode = focusMode;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001450
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001451 k.mParameters.focusingAreas = focusingAreas;
1452 k.mParameters.exposureCompensation = exposureCompensation;
1453 k.mParameters.autoExposureLock = autoExposureLock;
1454 k.mParameters.autoWhiteBalanceLock = autoWhiteBalanceLock;
1455 k.mParameters.meteringAreas = meteringAreas;
1456 k.mParameters.zoom = zoom;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001457
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001458 k.mParameters.videoWidth = videoWidth;
1459 k.mParameters.videoHeight = videoHeight;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001460
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001461 k.mParameters.recordingHint = recordingHint;
1462 k.mParameters.videoStabilization = videoStabilization;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001463
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001464 res = updatePreviewRequest(k.mParameters);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001465 if (res != OK) {
1466 ALOGE("%s: Camera %d: Unable to update preview request: %s (%d)",
1467 __FUNCTION__, mCameraId, strerror(-res), res);
1468 return res;
1469 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001470 res = updateCaptureRequest(k.mParameters);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001471 if (res != OK) {
1472 ALOGE("%s: Camera %d: Unable to update capture request: %s (%d)",
1473 __FUNCTION__, mCameraId, strerror(-res), res);
1474 return res;
1475 }
1476
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001477 res = updateRecordingRequest(k.mParameters);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001478 if (res != OK) {
1479 ALOGE("%s: Camera %d: Unable to update recording request: %s (%d)",
1480 __FUNCTION__, mCameraId, strerror(-res), res);
1481 return res;
1482 }
1483
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001484 if (mState == PREVIEW) {
1485 res = mDevice->setStreamingRequest(mPreviewRequest);
1486 if (res != OK) {
1487 ALOGE("%s: Camera %d: Error streaming new preview request: %s (%d)",
1488 __FUNCTION__, mCameraId, strerror(-res), res);
1489 return res;
1490 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001491 } else if (mState == RECORD || mState == VIDEO_SNAPSHOT) {
1492 res = mDevice->setStreamingRequest(mRecordingRequest);
1493 if (res != OK) {
1494 ALOGE("%s: Camera %d: Error streaming new record request: %s (%d)",
1495 __FUNCTION__, mCameraId, strerror(-res), res);
1496 return res;
1497 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001498 }
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001499
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001500 k.mParameters.paramsFlattened = params;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001501
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001502 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001503}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001504
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001505String8 Camera2Client::getParameters() const {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001506 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001507 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001508 if ( checkPid(__FUNCTION__) != OK) return String8();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001509
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001510 LockedParameters::ReadKey k(mParameters);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001511
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001512 // TODO: Deal with focus distances
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001513 return k.mParameters.paramsFlattened;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001514}
1515
1516status_t Camera2Client::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001517 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001518 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001519 status_t res;
1520 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001521
1522 ALOGV("%s: Camera %d: Command %d (%d, %d)", __FUNCTION__, mCameraId,
1523 cmd, arg1, arg2);
1524
1525 if (cmd == CAMERA_CMD_SET_DISPLAY_ORIENTATION) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001526 LockedParameters::Key k(mParameters);
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001527 int transform = degToTransform(arg1,
1528 mCameraFacing == CAMERA_FACING_FRONT);
1529 if (transform == -1) {
1530 ALOGE("%s: Camera %d: Error setting %d as display orientation value",
1531 __FUNCTION__, mCameraId, arg1);
1532 return BAD_VALUE;
1533 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001534 if (transform != k.mParameters.previewTransform &&
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001535 mPreviewStreamId != NO_STREAM) {
1536 mDevice->setStreamTransform(mPreviewStreamId, transform);
1537 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001538 k.mParameters.previewTransform = transform;
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001539 return OK;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001540 } else if (cmd == CAMERA_CMD_PING) {
1541 // Always ping back if access is proper and device is alive
1542 if (mState != DISCONNECTED) {
1543 return OK;
1544 } else {
1545 return NO_INIT;
1546 }
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001547 }
1548
1549 ALOGE("%s: Camera %d: Unimplemented command %d (%d, %d)", __FUNCTION__,
1550 mCameraId, cmd, arg1, arg2);
1551
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001552 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001553}
1554
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001555/** Device-related methods */
1556
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001557void Camera2Client::onCaptureAvailable() {
1558 ATRACE_CALL();
1559 status_t res;
1560 sp<ICameraClient> currentClient;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001561 ALOGV("%s: Camera %d: Still capture available", __FUNCTION__, mCameraId);
1562
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001563 CpuConsumer::LockedBuffer imgBuffer;
1564 {
1565 Mutex::Autolock icl(mICameraLock);
1566
1567 // TODO: Signal errors here upstream
1568 if (mState != STILL_CAPTURE && mState != VIDEO_SNAPSHOT) {
1569 ALOGE("%s: Camera %d: Still image produced unexpectedly!",
1570 __FUNCTION__, mCameraId);
1571 return;
1572 }
1573
1574 res = mCaptureConsumer->lockNextBuffer(&imgBuffer);
1575 if (res != OK) {
1576 ALOGE("%s: Camera %d: Error receiving still image buffer: %s (%d)",
1577 __FUNCTION__, mCameraId, strerror(-res), res);
1578 return;
1579 }
1580
1581 if (imgBuffer.format != HAL_PIXEL_FORMAT_BLOB) {
1582 ALOGE("%s: Camera %d: Unexpected format for still image: "
1583 "%x, expected %x", __FUNCTION__, mCameraId,
1584 imgBuffer.format,
1585 HAL_PIXEL_FORMAT_BLOB);
1586 mCaptureConsumer->unlockBuffer(imgBuffer);
1587 return;
1588 }
1589
1590 // TODO: Optimize this to avoid memcopy
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001591 void* captureMemory = mCaptureHeap->mHeap->getBase();
1592 size_t size = mCaptureHeap->mHeap->getSize();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001593 memcpy(captureMemory, imgBuffer.data, size);
1594
1595 mCaptureConsumer->unlockBuffer(imgBuffer);
1596
1597 currentClient = mCameraClient;
1598 switch (mState) {
1599 case STILL_CAPTURE:
1600 mState = STOPPED;
1601 break;
1602 case VIDEO_SNAPSHOT:
1603 mState = RECORD;
1604 break;
1605 default:
1606 ALOGE("%s: Camera %d: Unexpected state %d", __FUNCTION__,
1607 mCameraId, mState);
1608 break;
1609 }
1610 }
1611 // Call outside mICameraLock to allow re-entrancy from notification
1612 if (currentClient != 0) {
1613 currentClient->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001614 mCaptureHeap->mBuffers[0], NULL);
1615 }
1616}
1617
1618void Camera2Client::onRecordingFrameAvailable() {
1619 ATRACE_CALL();
1620 status_t res;
1621 sp<ICameraClient> currentClient;
1622 size_t heapIdx = 0;
1623 nsecs_t timestamp;
1624 {
1625 Mutex::Autolock icl(mICameraLock);
1626 // TODO: Signal errors here upstream
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001627 bool discardData = false;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001628 if (mState != RECORD && mState != VIDEO_SNAPSHOT) {
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001629 ALOGV("%s: Camera %d: Discarding recording image buffers received after "
1630 "recording done",
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001631 __FUNCTION__, mCameraId);
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001632 discardData = true;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001633 }
1634
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001635 buffer_handle_t imgBuffer;
1636 res = mRecordingConsumer->getNextBuffer(&imgBuffer, &timestamp);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001637 if (res != OK) {
1638 ALOGE("%s: Camera %d: Error receiving recording buffer: %s (%d)",
1639 __FUNCTION__, mCameraId, strerror(-res), res);
1640 return;
1641 }
1642
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001643 if (discardData) {
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001644 mRecordingConsumer->freeBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001645 return;
1646 }
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001647
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001648 if (mRecordingHeap == 0) {
1649 const size_t bufferSize = 4 + sizeof(buffer_handle_t);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001650 ALOGV("%s: Camera %d: Creating recording heap with %d buffers of "
1651 "size %d bytes", __FUNCTION__, mCameraId,
1652 kRecordingHeapCount, bufferSize);
1653 if (mRecordingHeap != 0) {
1654 ALOGV("%s: Camera %d: Previous heap has size %d "
1655 "(new will be %d) bytes", __FUNCTION__, mCameraId,
1656 mRecordingHeap->mHeap->getSize(),
1657 bufferSize * kRecordingHeapCount);
1658 }
1659 // Need to allocate memory for heap
1660 mRecordingHeap.clear();
1661
1662 mRecordingHeap = new Camera2Heap(bufferSize, kRecordingHeapCount,
1663 "Camera2Client::RecordingHeap");
1664 if (mRecordingHeap->mHeap->getSize() == 0) {
1665 ALOGE("%s: Camera %d: Unable to allocate memory for recording",
1666 __FUNCTION__, mCameraId);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001667 mRecordingConsumer->freeBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001668 return;
1669 }
1670 mRecordingHeapHead = 0;
1671 mRecordingHeapFree = kRecordingHeapCount;
1672 }
1673
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001674 if ( mRecordingHeapFree == 0) {
1675 ALOGE("%s: Camera %d: No free recording buffers, dropping frame",
1676 __FUNCTION__, mCameraId);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001677 mRecordingConsumer->freeBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001678 return;
1679 }
1680 heapIdx = mRecordingHeapHead;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001681 mRecordingHeapHead = (mRecordingHeapHead + 1) % kRecordingHeapCount;
1682 mRecordingHeapFree--;
1683
1684 ALOGV("%s: Camera %d: Timestamp %lld",
1685 __FUNCTION__, mCameraId, timestamp);
1686
1687 ssize_t offset;
1688 size_t size;
1689 sp<IMemoryHeap> heap =
1690 mRecordingHeap->mBuffers[heapIdx]->getMemory(&offset,
1691 &size);
1692
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001693 uint8_t *data = (uint8_t*)heap->getBase() + offset;
1694 uint32_t type = kMetadataBufferTypeGrallocSource;
1695 memcpy(data, &type, 4);
1696 memcpy(data + 4, &imgBuffer, sizeof(buffer_handle_t));
1697 ALOGV("%s: Camera %d: Sending out buffer_handle_t %p",
Eino-Ville Talvala803cbf62012-07-25 15:23:36 -07001698 __FUNCTION__, mCameraId, imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001699 currentClient = mCameraClient;
1700 }
1701 // Call outside mICameraLock to allow re-entrancy from notification
1702 if (currentClient != 0) {
1703 currentClient->dataCallbackTimestamp(timestamp,
1704 CAMERA_MSG_VIDEO_FRAME,
1705 mRecordingHeap->mBuffers[heapIdx]);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001706 }
1707}
1708
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001709camera_metadata_entry_t Camera2Client::staticInfo(uint32_t tag,
1710 size_t minCount, size_t maxCount) {
1711 status_t res;
1712 camera_metadata_entry_t entry;
1713 res = find_camera_metadata_entry(mDevice->info(),
1714 tag,
1715 &entry);
1716 if (CC_UNLIKELY( res != OK )) {
1717 const char* tagSection = get_camera_metadata_section_name(tag);
1718 if (tagSection == NULL) tagSection = "<unknown>";
1719 const char* tagName = get_camera_metadata_tag_name(tag);
1720 if (tagName == NULL) tagName = "<unknown>";
1721
1722 ALOGE("Error finding static metadata entry '%s.%s' (%x): %s (%d)",
1723 tagSection, tagName, tag, strerror(-res), res);
1724 entry.count = 0;
1725 entry.data.u8 = NULL;
1726 } else if (CC_UNLIKELY(
1727 (minCount != 0 && entry.count < minCount) ||
1728 (maxCount != 0 && entry.count > maxCount) ) ) {
1729 const char* tagSection = get_camera_metadata_section_name(tag);
1730 if (tagSection == NULL) tagSection = "<unknown>";
1731 const char* tagName = get_camera_metadata_tag_name(tag);
1732 if (tagName == NULL) tagName = "<unknown>";
1733 ALOGE("Malformed static metadata entry '%s.%s' (%x):"
1734 "Expected between %d and %d values, but got %d values",
1735 tagSection, tagName, tag, minCount, maxCount, entry.count);
1736 entry.count = 0;
1737 entry.data.u8 = NULL;
1738 }
1739
1740 return entry;
1741}
1742
1743/** Utility methods */
1744
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001745
1746status_t Camera2Client::buildDefaultParameters() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001747 ATRACE_CALL();
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001748 LockedParameters::Key k(mParameters);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001749
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001750 status_t res;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001751 CameraParameters params;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001752
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001753 camera_metadata_entry_t availableProcessedSizes =
1754 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES, 2);
1755 if (!availableProcessedSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001756
1757 // TODO: Pick more intelligently
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001758 k.mParameters.previewWidth = availableProcessedSizes.data.i32[0];
1759 k.mParameters.previewHeight = availableProcessedSizes.data.i32[1];
1760 k.mParameters.videoWidth = k.mParameters.previewWidth;
1761 k.mParameters.videoHeight = k.mParameters.previewHeight;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001762
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001763 params.setPreviewSize(k.mParameters.previewWidth, k.mParameters.previewHeight);
1764 params.setVideoSize(k.mParameters.videoWidth, k.mParameters.videoHeight);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001765 params.set(CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO,
1766 String8::format("%dx%d",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001767 k.mParameters.previewWidth, k.mParameters.previewHeight));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001768 {
1769 String8 supportedPreviewSizes;
1770 for (size_t i=0; i < availableProcessedSizes.count; i += 2) {
1771 if (i != 0) supportedPreviewSizes += ",";
1772 supportedPreviewSizes += String8::format("%dx%d",
1773 availableProcessedSizes.data.i32[i],
1774 availableProcessedSizes.data.i32[i+1]);
1775 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001776 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001777 supportedPreviewSizes);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001778 params.set(CameraParameters::KEY_SUPPORTED_VIDEO_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001779 supportedPreviewSizes);
1780 }
1781
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001782 camera_metadata_entry_t availableFpsRanges =
1783 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
1784 if (!availableFpsRanges.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001785
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001786 k.mParameters.previewFpsRange[0] = availableFpsRanges.data.i32[0];
1787 k.mParameters.previewFpsRange[1] = availableFpsRanges.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001788
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001789 params.set(CameraParameters::KEY_PREVIEW_FPS_RANGE,
1790 String8::format("%d,%d",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001791 k.mParameters.previewFpsRange[0],
1792 k.mParameters.previewFpsRange[1]));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001793
1794 {
1795 String8 supportedPreviewFpsRange;
1796 for (size_t i=0; i < availableFpsRanges.count; i += 2) {
1797 if (i != 0) supportedPreviewFpsRange += ",";
1798 supportedPreviewFpsRange += String8::format("(%d,%d)",
1799 availableFpsRanges.data.i32[i],
1800 availableFpsRanges.data.i32[i+1]);
1801 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001802 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001803 supportedPreviewFpsRange);
1804 }
1805
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001806 k.mParameters.previewFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001807 params.set(CameraParameters::KEY_PREVIEW_FORMAT,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001808 formatEnumToString(k.mParameters.previewFormat)); // NV21
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001809
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001810 k.mParameters.previewTransform = degToTransform(0,
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001811 mCameraFacing == CAMERA_FACING_FRONT);
1812
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001813 camera_metadata_entry_t availableFormats =
1814 staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
1815
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001816 {
1817 String8 supportedPreviewFormats;
1818 bool addComma = false;
1819 for (size_t i=0; i < availableFormats.count; i++) {
1820 if (addComma) supportedPreviewFormats += ",";
1821 addComma = true;
1822 switch (availableFormats.data.i32[i]) {
1823 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001824 supportedPreviewFormats +=
1825 CameraParameters::PIXEL_FORMAT_YUV422SP;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001826 break;
1827 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001828 supportedPreviewFormats +=
1829 CameraParameters::PIXEL_FORMAT_YUV420SP;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001830 break;
1831 case HAL_PIXEL_FORMAT_YCbCr_422_I:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001832 supportedPreviewFormats +=
1833 CameraParameters::PIXEL_FORMAT_YUV422I;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001834 break;
1835 case HAL_PIXEL_FORMAT_YV12:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001836 supportedPreviewFormats +=
1837 CameraParameters::PIXEL_FORMAT_YUV420P;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001838 break;
1839 case HAL_PIXEL_FORMAT_RGB_565:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001840 supportedPreviewFormats +=
1841 CameraParameters::PIXEL_FORMAT_RGB565;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001842 break;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001843 case HAL_PIXEL_FORMAT_RGBA_8888:
1844 supportedPreviewFormats +=
1845 CameraParameters::PIXEL_FORMAT_RGBA8888;
1846 break;
1847 // Not advertizing JPEG, RAW_SENSOR, etc, for preview formats
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001848 case HAL_PIXEL_FORMAT_RAW_SENSOR:
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001849 case HAL_PIXEL_FORMAT_BLOB:
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001850 addComma = false;
1851 break;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001852
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001853 default:
1854 ALOGW("%s: Camera %d: Unknown preview format: %x",
1855 __FUNCTION__, mCameraId, availableFormats.data.i32[i]);
1856 addComma = false;
1857 break;
1858 }
1859 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001860 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001861 supportedPreviewFormats);
1862 }
1863
1864 // PREVIEW_FRAME_RATE / SUPPORTED_PREVIEW_FRAME_RATES are deprecated, but
1865 // still have to do something sane for them
1866
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001867 params.set(CameraParameters::KEY_PREVIEW_FRAME_RATE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001868 k.mParameters.previewFpsRange[0]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001869
1870 {
1871 String8 supportedPreviewFrameRates;
1872 for (size_t i=0; i < availableFpsRanges.count; i += 2) {
1873 if (i != 0) supportedPreviewFrameRates += ",";
1874 supportedPreviewFrameRates += String8::format("%d",
1875 availableFpsRanges.data.i32[i]);
1876 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001877 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001878 supportedPreviewFrameRates);
1879 }
1880
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001881 camera_metadata_entry_t availableJpegSizes =
1882 staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES, 2);
1883 if (!availableJpegSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001884
1885 // TODO: Pick maximum
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001886 k.mParameters.pictureWidth = availableJpegSizes.data.i32[0];
1887 k.mParameters.pictureHeight = availableJpegSizes.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001888
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001889 params.setPictureSize(k.mParameters.pictureWidth,
1890 k.mParameters.pictureHeight);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001891
1892 {
1893 String8 supportedPictureSizes;
1894 for (size_t i=0; i < availableJpegSizes.count; i += 2) {
1895 if (i != 0) supportedPictureSizes += ",";
1896 supportedPictureSizes += String8::format("%dx%d",
1897 availableJpegSizes.data.i32[i],
1898 availableJpegSizes.data.i32[i+1]);
1899 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001900 params.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001901 supportedPictureSizes);
1902 }
1903
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001904 params.setPictureFormat(CameraParameters::PIXEL_FORMAT_JPEG);
1905 params.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS,
1906 CameraParameters::PIXEL_FORMAT_JPEG);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001907
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001908 camera_metadata_entry_t availableJpegThumbnailSizes =
1909 staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES, 2);
1910 if (!availableJpegThumbnailSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001911
1912 // TODO: Pick default thumbnail size sensibly
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001913 k.mParameters.jpegThumbSize[0] = availableJpegThumbnailSizes.data.i32[0];
1914 k.mParameters.jpegThumbSize[1] = availableJpegThumbnailSizes.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001915
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001916 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001917 k.mParameters.jpegThumbSize[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001918 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001919 k.mParameters.jpegThumbSize[1]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001920
1921 {
1922 String8 supportedJpegThumbSizes;
1923 for (size_t i=0; i < availableJpegThumbnailSizes.count; i += 2) {
1924 if (i != 0) supportedJpegThumbSizes += ",";
1925 supportedJpegThumbSizes += String8::format("%dx%d",
1926 availableJpegThumbnailSizes.data.i32[i],
1927 availableJpegThumbnailSizes.data.i32[i+1]);
1928 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001929 params.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001930 supportedJpegThumbSizes);
1931 }
1932
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001933 k.mParameters.jpegThumbQuality = 90;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001934 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001935 k.mParameters.jpegThumbQuality);
1936 k.mParameters.jpegQuality = 90;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001937 params.set(CameraParameters::KEY_JPEG_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001938 k.mParameters.jpegQuality);
1939 k.mParameters.jpegRotation = 0;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001940 params.set(CameraParameters::KEY_ROTATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001941 k.mParameters.jpegRotation);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001942
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001943 k.mParameters.gpsEnabled = false;
1944 k.mParameters.gpsProcessingMethod = "unknown";
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001945 // GPS fields in CameraParameters are not set by implementation
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001946
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001947 k.mParameters.wbMode = ANDROID_CONTROL_AWB_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001948 params.set(CameraParameters::KEY_WHITE_BALANCE,
1949 CameraParameters::WHITE_BALANCE_AUTO);
1950
1951 camera_metadata_entry_t availableWhiteBalanceModes =
1952 staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001953 {
1954 String8 supportedWhiteBalance;
1955 bool addComma = false;
1956 for (size_t i=0; i < availableWhiteBalanceModes.count; i++) {
1957 if (addComma) supportedWhiteBalance += ",";
1958 addComma = true;
1959 switch (availableWhiteBalanceModes.data.u8[i]) {
1960 case ANDROID_CONTROL_AWB_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001961 supportedWhiteBalance +=
1962 CameraParameters::WHITE_BALANCE_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001963 break;
1964 case ANDROID_CONTROL_AWB_INCANDESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001965 supportedWhiteBalance +=
1966 CameraParameters::WHITE_BALANCE_INCANDESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001967 break;
1968 case ANDROID_CONTROL_AWB_FLUORESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001969 supportedWhiteBalance +=
1970 CameraParameters::WHITE_BALANCE_FLUORESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001971 break;
1972 case ANDROID_CONTROL_AWB_WARM_FLUORESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001973 supportedWhiteBalance +=
1974 CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001975 break;
1976 case ANDROID_CONTROL_AWB_DAYLIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001977 supportedWhiteBalance +=
1978 CameraParameters::WHITE_BALANCE_DAYLIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001979 break;
1980 case ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001981 supportedWhiteBalance +=
1982 CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001983 break;
1984 case ANDROID_CONTROL_AWB_TWILIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001985 supportedWhiteBalance +=
1986 CameraParameters::WHITE_BALANCE_TWILIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001987 break;
1988 case ANDROID_CONTROL_AWB_SHADE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001989 supportedWhiteBalance +=
1990 CameraParameters::WHITE_BALANCE_SHADE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001991 break;
1992 // Skipping values not mappable to v1 API
1993 case ANDROID_CONTROL_AWB_OFF:
1994 addComma = false;
1995 break;
1996 default:
1997 ALOGW("%s: Camera %d: Unknown white balance value: %d",
1998 __FUNCTION__, mCameraId,
1999 availableWhiteBalanceModes.data.u8[i]);
2000 addComma = false;
2001 break;
2002 }
2003 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002004 params.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002005 supportedWhiteBalance);
2006 }
2007
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002008 k.mParameters.effectMode = ANDROID_CONTROL_EFFECT_OFF;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002009 params.set(CameraParameters::KEY_EFFECT,
2010 CameraParameters::EFFECT_NONE);
2011
2012 camera_metadata_entry_t availableEffects =
2013 staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
2014 if (!availableEffects.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002015 {
2016 String8 supportedEffects;
2017 bool addComma = false;
2018 for (size_t i=0; i < availableEffects.count; i++) {
2019 if (addComma) supportedEffects += ",";
2020 addComma = true;
2021 switch (availableEffects.data.u8[i]) {
2022 case ANDROID_CONTROL_EFFECT_OFF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002023 supportedEffects +=
2024 CameraParameters::EFFECT_NONE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002025 break;
2026 case ANDROID_CONTROL_EFFECT_MONO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002027 supportedEffects +=
2028 CameraParameters::EFFECT_MONO;
2029 break;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002030 case ANDROID_CONTROL_EFFECT_NEGATIVE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002031 supportedEffects +=
2032 CameraParameters::EFFECT_NEGATIVE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002033 break;
2034 case ANDROID_CONTROL_EFFECT_SOLARIZE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002035 supportedEffects +=
2036 CameraParameters::EFFECT_SOLARIZE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002037 break;
2038 case ANDROID_CONTROL_EFFECT_SEPIA:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002039 supportedEffects +=
2040 CameraParameters::EFFECT_SEPIA;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002041 break;
2042 case ANDROID_CONTROL_EFFECT_POSTERIZE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002043 supportedEffects +=
2044 CameraParameters::EFFECT_POSTERIZE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002045 break;
2046 case ANDROID_CONTROL_EFFECT_WHITEBOARD:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002047 supportedEffects +=
2048 CameraParameters::EFFECT_WHITEBOARD;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002049 break;
2050 case ANDROID_CONTROL_EFFECT_BLACKBOARD:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002051 supportedEffects +=
2052 CameraParameters::EFFECT_BLACKBOARD;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002053 break;
2054 case ANDROID_CONTROL_EFFECT_AQUA:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002055 supportedEffects +=
2056 CameraParameters::EFFECT_AQUA;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002057 break;
2058 default:
2059 ALOGW("%s: Camera %d: Unknown effect value: %d",
2060 __FUNCTION__, mCameraId, availableEffects.data.u8[i]);
2061 addComma = false;
2062 break;
2063 }
2064 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002065 params.set(CameraParameters::KEY_SUPPORTED_EFFECTS, supportedEffects);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002066 }
2067
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002068 k.mParameters.antibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002069 params.set(CameraParameters::KEY_ANTIBANDING,
2070 CameraParameters::ANTIBANDING_AUTO);
2071
2072 camera_metadata_entry_t availableAntibandingModes =
2073 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
2074 if (!availableAntibandingModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002075 {
2076 String8 supportedAntibanding;
2077 bool addComma = false;
2078 for (size_t i=0; i < availableAntibandingModes.count; i++) {
2079 if (addComma) supportedAntibanding += ",";
2080 addComma = true;
2081 switch (availableAntibandingModes.data.u8[i]) {
2082 case ANDROID_CONTROL_AE_ANTIBANDING_OFF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002083 supportedAntibanding +=
2084 CameraParameters::ANTIBANDING_OFF;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002085 break;
2086 case ANDROID_CONTROL_AE_ANTIBANDING_50HZ:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002087 supportedAntibanding +=
2088 CameraParameters::ANTIBANDING_50HZ;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002089 break;
2090 case ANDROID_CONTROL_AE_ANTIBANDING_60HZ:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002091 supportedAntibanding +=
2092 CameraParameters::ANTIBANDING_60HZ;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002093 break;
2094 case ANDROID_CONTROL_AE_ANTIBANDING_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002095 supportedAntibanding +=
2096 CameraParameters::ANTIBANDING_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002097 break;
2098 default:
2099 ALOGW("%s: Camera %d: Unknown antibanding value: %d",
2100 __FUNCTION__, mCameraId,
2101 availableAntibandingModes.data.u8[i]);
2102 addComma = false;
2103 break;
2104 }
2105 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002106 params.set(CameraParameters::KEY_SUPPORTED_ANTIBANDING,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002107 supportedAntibanding);
2108 }
2109
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002110 k.mParameters.sceneMode = ANDROID_CONTROL_OFF;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002111 params.set(CameraParameters::KEY_SCENE_MODE,
2112 CameraParameters::SCENE_MODE_AUTO);
2113
2114 camera_metadata_entry_t availableSceneModes =
2115 staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
2116 if (!availableSceneModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002117 {
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002118 String8 supportedSceneModes(CameraParameters::SCENE_MODE_AUTO);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002119 bool addComma = true;
2120 bool noSceneModes = false;
2121 for (size_t i=0; i < availableSceneModes.count; i++) {
2122 if (addComma) supportedSceneModes += ",";
2123 addComma = true;
2124 switch (availableSceneModes.data.u8[i]) {
2125 case ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED:
2126 noSceneModes = true;
2127 break;
2128 case ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY:
2129 // Not in old API
2130 addComma = false;
2131 break;
2132 case ANDROID_CONTROL_SCENE_MODE_ACTION:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002133 supportedSceneModes +=
2134 CameraParameters::SCENE_MODE_ACTION;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002135 break;
2136 case ANDROID_CONTROL_SCENE_MODE_PORTRAIT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002137 supportedSceneModes +=
2138 CameraParameters::SCENE_MODE_PORTRAIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002139 break;
2140 case ANDROID_CONTROL_SCENE_MODE_LANDSCAPE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002141 supportedSceneModes +=
2142 CameraParameters::SCENE_MODE_LANDSCAPE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002143 break;
2144 case ANDROID_CONTROL_SCENE_MODE_NIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002145 supportedSceneModes +=
2146 CameraParameters::SCENE_MODE_NIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002147 break;
2148 case ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002149 supportedSceneModes +=
2150 CameraParameters::SCENE_MODE_NIGHT_PORTRAIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002151 break;
2152 case ANDROID_CONTROL_SCENE_MODE_THEATRE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002153 supportedSceneModes +=
2154 CameraParameters::SCENE_MODE_THEATRE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002155 break;
2156 case ANDROID_CONTROL_SCENE_MODE_BEACH:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002157 supportedSceneModes +=
2158 CameraParameters::SCENE_MODE_BEACH;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002159 break;
2160 case ANDROID_CONTROL_SCENE_MODE_SNOW:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002161 supportedSceneModes +=
2162 CameraParameters::SCENE_MODE_SNOW;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002163 break;
2164 case ANDROID_CONTROL_SCENE_MODE_SUNSET:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002165 supportedSceneModes +=
2166 CameraParameters::SCENE_MODE_SUNSET;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002167 break;
2168 case ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002169 supportedSceneModes +=
2170 CameraParameters::SCENE_MODE_STEADYPHOTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002171 break;
2172 case ANDROID_CONTROL_SCENE_MODE_FIREWORKS:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002173 supportedSceneModes +=
2174 CameraParameters::SCENE_MODE_FIREWORKS;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002175 break;
2176 case ANDROID_CONTROL_SCENE_MODE_SPORTS:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002177 supportedSceneModes +=
2178 CameraParameters::SCENE_MODE_SPORTS;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002179 break;
2180 case ANDROID_CONTROL_SCENE_MODE_PARTY:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002181 supportedSceneModes +=
2182 CameraParameters::SCENE_MODE_PARTY;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002183 break;
2184 case ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002185 supportedSceneModes +=
2186 CameraParameters::SCENE_MODE_CANDLELIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002187 break;
2188 case ANDROID_CONTROL_SCENE_MODE_BARCODE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002189 supportedSceneModes +=
2190 CameraParameters::SCENE_MODE_BARCODE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002191 break;
2192 default:
2193 ALOGW("%s: Camera %d: Unknown scene mode value: %d",
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002194 __FUNCTION__, mCameraId,
2195 availableSceneModes.data.u8[i]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002196 addComma = false;
2197 break;
2198 }
2199 }
2200 if (!noSceneModes) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002201 params.set(CameraParameters::KEY_SUPPORTED_SCENE_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002202 supportedSceneModes);
2203 }
2204 }
2205
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002206 camera_metadata_entry_t flashAvailable =
2207 staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
2208 if (!flashAvailable.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002209
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002210 camera_metadata_entry_t availableAeModes =
2211 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
2212 if (!availableAeModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002213
2214 if (flashAvailable.data.u8[0]) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002215 k.mParameters.flashMode = Parameters::FLASH_MODE_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002216 params.set(CameraParameters::KEY_FLASH_MODE,
2217 CameraParameters::FLASH_MODE_AUTO);
2218
2219 String8 supportedFlashModes(CameraParameters::FLASH_MODE_OFF);
2220 supportedFlashModes = supportedFlashModes +
2221 "," + CameraParameters::FLASH_MODE_AUTO +
2222 "," + CameraParameters::FLASH_MODE_ON +
2223 "," + CameraParameters::FLASH_MODE_TORCH;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002224 for (size_t i=0; i < availableAeModes.count; i++) {
2225 if (availableAeModes.data.u8[i] ==
2226 ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002227 supportedFlashModes = supportedFlashModes + "," +
2228 CameraParameters::FLASH_MODE_RED_EYE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002229 break;
2230 }
2231 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002232 params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002233 supportedFlashModes);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002234 } else {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002235 k.mParameters.flashMode = Parameters::FLASH_MODE_OFF;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002236 params.set(CameraParameters::KEY_FLASH_MODE,
2237 CameraParameters::FLASH_MODE_OFF);
2238 params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
2239 CameraParameters::FLASH_MODE_OFF);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002240 }
2241
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002242 camera_metadata_entry_t minFocusDistance =
2243 staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE, 1, 1);
2244 if (!minFocusDistance.count) return NO_INIT;
2245
2246 camera_metadata_entry_t availableAfModes =
2247 staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
2248 if (!availableAfModes.count) return NO_INIT;
2249
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002250 if (minFocusDistance.data.f[0] == 0) {
2251 // Fixed-focus lens
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002252 k.mParameters.focusMode = Parameters::FOCUS_MODE_FIXED;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002253 params.set(CameraParameters::KEY_FOCUS_MODE,
2254 CameraParameters::FOCUS_MODE_FIXED);
2255 params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
2256 CameraParameters::FOCUS_MODE_FIXED);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002257 } else {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002258 k.mParameters.focusMode = Parameters::FOCUS_MODE_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002259 params.set(CameraParameters::KEY_FOCUS_MODE,
2260 CameraParameters::FOCUS_MODE_AUTO);
2261 String8 supportedFocusModes(CameraParameters::FOCUS_MODE_FIXED);
2262 supportedFocusModes = supportedFocusModes + "," +
2263 CameraParameters::FOCUS_MODE_INFINITY;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002264 bool addComma = true;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002265
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002266 for (size_t i=0; i < availableAfModes.count; i++) {
2267 if (addComma) supportedFocusModes += ",";
2268 addComma = true;
2269 switch (availableAfModes.data.u8[i]) {
2270 case ANDROID_CONTROL_AF_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002271 supportedFocusModes +=
2272 CameraParameters::FOCUS_MODE_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002273 break;
2274 case ANDROID_CONTROL_AF_MACRO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002275 supportedFocusModes +=
2276 CameraParameters::FOCUS_MODE_MACRO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002277 break;
2278 case ANDROID_CONTROL_AF_CONTINUOUS_VIDEO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002279 supportedFocusModes +=
2280 CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002281 break;
2282 case ANDROID_CONTROL_AF_CONTINUOUS_PICTURE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002283 supportedFocusModes +=
2284 CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002285 break;
2286 case ANDROID_CONTROL_AF_EDOF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002287 supportedFocusModes +=
2288 CameraParameters::FOCUS_MODE_EDOF;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002289 break;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002290 // Not supported in old API
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002291 case ANDROID_CONTROL_AF_OFF:
2292 addComma = false;
2293 break;
2294 default:
2295 ALOGW("%s: Camera %d: Unknown AF mode value: %d",
2296 __FUNCTION__, mCameraId, availableAfModes.data.u8[i]);
2297 addComma = false;
2298 break;
2299 }
2300 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002301 params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002302 supportedFocusModes);
2303 }
2304
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002305 camera_metadata_entry_t max3aRegions =
2306 staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1);
2307 if (!max3aRegions.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002308
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002309 params.set(CameraParameters::KEY_MAX_NUM_FOCUS_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002310 max3aRegions.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002311 params.set(CameraParameters::KEY_FOCUS_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002312 "(0,0,0,0,0)");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002313 k.mParameters.focusingAreas.clear();
2314 k.mParameters.focusingAreas.add(Parameters::Area(0,0,0,0,0));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002315
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002316 camera_metadata_entry_t availableFocalLengths =
2317 staticInfo(ANDROID_LENS_AVAILABLE_FOCAL_LENGTHS);
2318 if (!availableFocalLengths.count) return NO_INIT;
2319
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002320 float minFocalLength = availableFocalLengths.data.f[0];
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002321 params.setFloat(CameraParameters::KEY_FOCAL_LENGTH, minFocalLength);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002322
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002323 camera_metadata_entry_t sensorSize =
2324 staticInfo(ANDROID_SENSOR_PHYSICAL_SIZE, 2, 2);
2325 if (!sensorSize.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002326
2327 // The fields of view here assume infinity focus, maximum wide angle
2328 float horizFov = 180 / M_PI *
2329 2 * atanf(sensorSize.data.f[0] / (2 * minFocalLength));
2330 float vertFov = 180 / M_PI *
2331 2 * atanf(sensorSize.data.f[1] / (2 * minFocalLength));
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002332 params.setFloat(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, horizFov);
2333 params.setFloat(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, vertFov);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002334
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002335 k.mParameters.exposureCompensation = 0;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002336 params.set(CameraParameters::KEY_EXPOSURE_COMPENSATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002337 k.mParameters.exposureCompensation);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002338
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002339 camera_metadata_entry_t exposureCompensationRange =
2340 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE, 2, 2);
2341 if (!exposureCompensationRange.count) return NO_INIT;
2342
2343 params.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002344 exposureCompensationRange.data.i32[1]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002345 params.set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002346 exposureCompensationRange.data.i32[0]);
2347
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002348 camera_metadata_entry_t exposureCompensationStep =
2349 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_STEP, 1, 1);
2350 if (!exposureCompensationStep.count) return NO_INIT;
2351
2352 params.setFloat(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP,
Eino-Ville Talvalad6f8e082012-08-02 16:00:35 -07002353 (float)exposureCompensationStep.data.r[0].numerator /
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002354 exposureCompensationStep.data.r[0].denominator);
2355
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002356 k.mParameters.autoExposureLock = false;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002357 params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK,
2358 CameraParameters::FALSE);
2359 params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED,
2360 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002361
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002362 k.mParameters.autoWhiteBalanceLock = false;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002363 params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK,
2364 CameraParameters::FALSE);
2365 params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED,
2366 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002367
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002368 k.mParameters.meteringAreas.add(Parameters::Area(0, 0, 0, 0, 0));
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002369 params.set(CameraParameters::KEY_MAX_NUM_METERING_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002370 max3aRegions.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002371 params.set(CameraParameters::KEY_METERING_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002372 "(0,0,0,0,0)");
2373
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002374 k.mParameters.zoom = 0;
2375 params.set(CameraParameters::KEY_ZOOM, k.mParameters.zoom);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002376 params.set(CameraParameters::KEY_MAX_ZOOM, NUM_ZOOM_STEPS - 1);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002377
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002378 camera_metadata_entry_t maxDigitalZoom =
2379 staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM, 1, 1);
2380 if (!maxDigitalZoom.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002381
2382 {
2383 String8 zoomRatios;
2384 float zoom = 1.f;
2385 float zoomIncrement = (maxDigitalZoom.data.f[0] - zoom) /
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002386 (NUM_ZOOM_STEPS-1);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002387 bool addComma = false;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002388 for (size_t i=0; i < NUM_ZOOM_STEPS; i++) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002389 if (addComma) zoomRatios += ",";
2390 addComma = true;
2391 zoomRatios += String8::format("%d", static_cast<int>(zoom * 100));
2392 zoom += zoomIncrement;
2393 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002394 params.set(CameraParameters::KEY_ZOOM_RATIOS, zoomRatios);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002395 }
2396
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002397 params.set(CameraParameters::KEY_ZOOM_SUPPORTED,
2398 CameraParameters::TRUE);
2399 params.set(CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED,
2400 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002401
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002402 params.set(CameraParameters::KEY_FOCUS_DISTANCES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002403 "Infinity,Infinity,Infinity");
2404
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002405 camera_metadata_entry_t maxFacesDetected =
2406 staticInfo(ANDROID_STATS_MAX_FACE_COUNT, 1, 1);
2407 params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002408 maxFacesDetected.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002409 params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002410 0);
2411
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002412 params.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT,
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002413 CameraParameters::PIXEL_FORMAT_ANDROID_OPAQUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002414
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002415 params.set(CameraParameters::KEY_RECORDING_HINT,
2416 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002417
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002418 params.set(CameraParameters::KEY_VIDEO_SNAPSHOT_SUPPORTED,
2419 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002420
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002421 params.set(CameraParameters::KEY_VIDEO_STABILIZATION,
2422 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002423
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002424 camera_metadata_entry_t availableVideoStabilizationModes =
2425 staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
2426 if (!availableVideoStabilizationModes.count) return NO_INIT;
2427
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002428 if (availableVideoStabilizationModes.count > 1) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002429 params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
2430 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002431 } else {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002432 params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
2433 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002434 }
2435
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002436 // Always use metadata mode for recording
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002437 k.mParameters.storeMetadataInBuffers = true;
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002438
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002439 k.mParameters.paramsFlattened = params.flatten();
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002440
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002441 return OK;
2442}
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07002443
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002444status_t Camera2Client::updatePreviewStream(const Parameters &params) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002445 ATRACE_CALL();
2446 status_t res;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002447
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002448 if (mPreviewStreamId != NO_STREAM) {
2449 // Check if stream parameters have to change
2450 uint32_t currentWidth, currentHeight;
2451 res = mDevice->getStreamInfo(mPreviewStreamId,
2452 &currentWidth, &currentHeight, 0);
2453 if (res != OK) {
2454 ALOGE("%s: Camera %d: Error querying preview stream info: "
2455 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2456 return res;
2457 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002458 if (currentWidth != (uint32_t)params.previewWidth ||
2459 currentHeight != (uint32_t)params.previewHeight) {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -07002460 ALOGV("%s: Camera %d: Preview size switch: %d x %d -> %d x %d",
2461 __FUNCTION__, mCameraId, currentWidth, currentHeight,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002462 params.previewWidth, params.previewHeight);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002463 res = mDevice->waitUntilDrained();
2464 if (res != OK) {
2465 ALOGE("%s: Camera %d: Error waiting for preview to drain: "
2466 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2467 return res;
2468 }
2469 res = mDevice->deleteStream(mPreviewStreamId);
2470 if (res != OK) {
2471 ALOGE("%s: Camera %d: Unable to delete old output stream "
2472 "for preview: %s (%d)", __FUNCTION__, mCameraId,
2473 strerror(-res), res);
2474 return res;
2475 }
2476 mPreviewStreamId = NO_STREAM;
2477 }
2478 }
2479
2480 if (mPreviewStreamId == NO_STREAM) {
2481 res = mDevice->createStream(mPreviewWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002482 params.previewWidth, params.previewHeight,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002483 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0,
2484 &mPreviewStreamId);
2485 if (res != OK) {
2486 ALOGE("%s: Camera %d: Unable to create preview stream: %s (%d)",
2487 __FUNCTION__, mCameraId, strerror(-res), res);
2488 return res;
2489 }
2490 }
2491
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07002492 res = mDevice->setStreamTransform(mPreviewStreamId,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002493 params.previewTransform);
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07002494 if (res != OK) {
2495 ALOGE("%s: Camera %d: Unable to set preview stream transform: "
2496 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2497 return res;
2498 }
2499
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002500 return OK;
2501}
2502
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002503status_t Camera2Client::updatePreviewRequest(const Parameters &params) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07002504 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002505 status_t res;
2506 if (mPreviewRequest == NULL) {
2507 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
2508 &mPreviewRequest);
2509 if (res != OK) {
2510 ALOGE("%s: Camera %d: Unable to create default preview request: "
2511 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2512 return res;
2513 }
2514 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002515
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002516 res = updateRequestCommon(mPreviewRequest, params);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002517 if (res != OK) {
2518 ALOGE("%s: Camera %d: Unable to update common entries of preview "
2519 "request: %s (%d)", __FUNCTION__, mCameraId,
2520 strerror(-res), res);
2521 return res;
2522 }
2523
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002524 return OK;
2525}
2526
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002527status_t Camera2Client::updateCaptureStream(const Parameters &params) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002528 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002529 status_t res;
2530 // Find out buffer size for JPEG
2531 camera_metadata_entry_t maxJpegSize =
2532 staticInfo(ANDROID_JPEG_MAX_SIZE);
2533 if (maxJpegSize.count == 0) {
2534 ALOGE("%s: Camera %d: Can't find ANDROID_JPEG_MAX_SIZE!",
2535 __FUNCTION__, mCameraId);
2536 return INVALID_OPERATION;
2537 }
2538
2539 if (mCaptureConsumer == 0) {
2540 // Create CPU buffer queue endpoint
2541 mCaptureConsumer = new CpuConsumer(1);
2542 mCaptureConsumer->setFrameAvailableListener(new CaptureWaiter(this));
2543 mCaptureConsumer->setName(String8("Camera2Client::CaptureConsumer"));
2544 mCaptureWindow = new SurfaceTextureClient(
2545 mCaptureConsumer->getProducerInterface());
2546 // Create memory for API consumption
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002547 mCaptureHeap = new Camera2Heap(maxJpegSize.data.i32[0], 1,
2548 "Camera2Client::CaptureHeap");
2549 if (mCaptureHeap->mHeap->getSize() == 0) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002550 ALOGE("%s: Camera %d: Unable to allocate memory for capture",
2551 __FUNCTION__, mCameraId);
2552 return NO_MEMORY;
2553 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002554 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002555
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002556 if (mCaptureStreamId != NO_STREAM) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002557 // Check if stream parameters have to change
2558 uint32_t currentWidth, currentHeight;
2559 res = mDevice->getStreamInfo(mCaptureStreamId,
2560 &currentWidth, &currentHeight, 0);
2561 if (res != OK) {
2562 ALOGE("%s: Camera %d: Error querying capture output stream info: "
2563 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2564 return res;
2565 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002566 if (currentWidth != (uint32_t)params.pictureWidth ||
2567 currentHeight != (uint32_t)params.pictureHeight) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002568 res = mDevice->deleteStream(mCaptureStreamId);
2569 if (res != OK) {
2570 ALOGE("%s: Camera %d: Unable to delete old output stream "
2571 "for capture: %s (%d)", __FUNCTION__, mCameraId,
2572 strerror(-res), res);
2573 return res;
2574 }
2575 mCaptureStreamId = NO_STREAM;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002576 }
2577 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002578
2579 if (mCaptureStreamId == NO_STREAM) {
2580 // Create stream for HAL production
2581 res = mDevice->createStream(mCaptureWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002582 params.pictureWidth, params.pictureHeight,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002583 HAL_PIXEL_FORMAT_BLOB, maxJpegSize.data.i32[0],
2584 &mCaptureStreamId);
2585 if (res != OK) {
2586 ALOGE("%s: Camera %d: Can't create output stream for capture: "
2587 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2588 return res;
2589 }
2590
2591 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002592 return OK;
2593}
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002594
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002595status_t Camera2Client::updateCaptureRequest(const Parameters &params) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002596 ATRACE_CALL();
2597 status_t res;
2598 if (mCaptureRequest == NULL) {
2599 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_STILL_CAPTURE,
2600 &mCaptureRequest);
2601 if (res != OK) {
2602 ALOGE("%s: Camera %d: Unable to create default still image request:"
2603 " %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2604 return res;
2605 }
2606 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002607
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002608 res = updateRequestCommon(mCaptureRequest, params);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002609 if (res != OK) {
2610 ALOGE("%s: Camera %d: Unable to update common entries of capture "
2611 "request: %s (%d)", __FUNCTION__, mCameraId,
2612 strerror(-res), res);
2613 return res;
2614 }
2615
2616 res = updateEntry(mCaptureRequest,
2617 ANDROID_JPEG_THUMBNAIL_SIZE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002618 params.jpegThumbSize, 2);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002619 if (res != OK) return res;
2620 res = updateEntry(mCaptureRequest,
2621 ANDROID_JPEG_THUMBNAIL_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002622 &params.jpegThumbQuality, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002623 if (res != OK) return res;
2624 res = updateEntry(mCaptureRequest,
2625 ANDROID_JPEG_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002626 &params.jpegQuality, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002627 if (res != OK) return res;
2628 res = updateEntry(mCaptureRequest,
2629 ANDROID_JPEG_ORIENTATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002630 &params.jpegRotation, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002631 if (res != OK) return res;
2632
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002633 if (params.gpsEnabled) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002634 res = updateEntry(mCaptureRequest,
2635 ANDROID_JPEG_GPS_COORDINATES,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002636 params.gpsCoordinates, 3);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002637 if (res != OK) return res;
2638 res = updateEntry(mCaptureRequest,
2639 ANDROID_JPEG_GPS_TIMESTAMP,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002640 &params.gpsTimestamp, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002641 if (res != OK) return res;
2642 res = updateEntry(mCaptureRequest,
2643 ANDROID_JPEG_GPS_PROCESSING_METHOD,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002644 params.gpsProcessingMethod.string(),
2645 params.gpsProcessingMethod.size());
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002646 if (res != OK) return res;
2647 } else {
2648 res = deleteEntry(mCaptureRequest,
2649 ANDROID_JPEG_GPS_COORDINATES);
2650 if (res != OK) return res;
2651 res = deleteEntry(mCaptureRequest,
2652 ANDROID_JPEG_GPS_TIMESTAMP);
2653 if (res != OK) return res;
2654 res = deleteEntry(mCaptureRequest,
2655 ANDROID_JPEG_GPS_PROCESSING_METHOD);
2656 if (res != OK) return res;
2657 }
2658
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002659 return OK;
2660}
2661
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002662status_t Camera2Client::updateRecordingRequest(const Parameters &params) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002663 ATRACE_CALL();
2664 status_t res;
2665 if (mRecordingRequest == NULL) {
2666 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_VIDEO_RECORD,
2667 &mRecordingRequest);
2668 if (res != OK) {
2669 ALOGE("%s: Camera %d: Unable to create default recording request:"
2670 " %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2671 return res;
2672 }
2673 }
2674
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002675 res = updateRequestCommon(mRecordingRequest, params);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002676 if (res != OK) {
2677 ALOGE("%s: Camera %d: Unable to update common entries of recording "
2678 "request: %s (%d)", __FUNCTION__, mCameraId,
2679 strerror(-res), res);
2680 return res;
2681 }
2682
2683 return OK;
2684}
2685
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002686status_t Camera2Client::updateRecordingStream(const Parameters &params) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002687 status_t res;
2688
2689 if (mRecordingConsumer == 0) {
2690 // Create CPU buffer queue endpoint
Eino-Ville Talvala803cbf62012-07-25 15:23:36 -07002691 mRecordingConsumer = new MediaConsumer(kRecordingHeapCount);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002692 mRecordingConsumer->setFrameAvailableListener(new RecordingWaiter(this));
2693 mRecordingConsumer->setName(String8("Camera2Client::RecordingConsumer"));
2694 mRecordingWindow = new SurfaceTextureClient(
2695 mRecordingConsumer->getProducerInterface());
2696 // Allocate memory later, since we don't know buffer size until receipt
2697 }
2698
2699 if (mRecordingStreamId != NO_STREAM) {
2700 // Check if stream parameters have to change
2701 uint32_t currentWidth, currentHeight;
2702 res = mDevice->getStreamInfo(mRecordingStreamId,
2703 &currentWidth, &currentHeight, 0);
2704 if (res != OK) {
2705 ALOGE("%s: Camera %d: Error querying recording output stream info: "
2706 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2707 return res;
2708 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002709 if (currentWidth != (uint32_t)params.videoWidth ||
2710 currentHeight != (uint32_t)params.videoHeight) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002711 // TODO: Should wait to be sure previous recording has finished
2712 res = mDevice->deleteStream(mRecordingStreamId);
2713 if (res != OK) {
2714 ALOGE("%s: Camera %d: Unable to delete old output stream "
2715 "for recording: %s (%d)", __FUNCTION__, mCameraId,
2716 strerror(-res), res);
2717 return res;
2718 }
2719 mRecordingStreamId = NO_STREAM;
2720 }
2721 }
2722
2723 if (mRecordingStreamId == NO_STREAM) {
2724 res = mDevice->createStream(mRecordingWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002725 params.videoWidth, params.videoHeight,
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002726 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0, &mRecordingStreamId);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002727 if (res != OK) {
2728 ALOGE("%s: Camera %d: Can't create output stream for recording: "
2729 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2730 return res;
2731 }
2732 }
2733
2734 return OK;
2735}
2736
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002737status_t Camera2Client::updateRequestCommon(camera_metadata_t *request,
2738 const Parameters &params) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002739 ATRACE_CALL();
2740 status_t res;
2741 res = updateEntry(request,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002742 ANDROID_CONTROL_AE_TARGET_FPS_RANGE, params.previewFpsRange, 2);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002743 if (res != OK) return res;
2744
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002745 uint8_t wbMode = params.autoWhiteBalanceLock ?
2746 ANDROID_CONTROL_AWB_LOCKED : params.wbMode;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002747 res = updateEntry(request,
2748 ANDROID_CONTROL_AWB_MODE, &wbMode, 1);
2749 if (res != OK) return res;
2750 res = updateEntry(request,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002751 ANDROID_CONTROL_EFFECT_MODE, &params.effectMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002752 if (res != OK) return res;
2753 res = updateEntry(request,
2754 ANDROID_CONTROL_AE_ANTIBANDING_MODE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002755 &params.antibandingMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002756 if (res != OK) return res;
2757
2758 uint8_t controlMode =
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002759 (params.sceneMode == ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED) ?
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002760 ANDROID_CONTROL_AUTO : ANDROID_CONTROL_USE_SCENE_MODE;
2761 res = updateEntry(request,
2762 ANDROID_CONTROL_MODE, &controlMode, 1);
2763 if (res != OK) return res;
2764 if (controlMode == ANDROID_CONTROL_USE_SCENE_MODE) {
2765 res = updateEntry(request,
2766 ANDROID_CONTROL_SCENE_MODE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002767 &params.sceneMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002768 if (res != OK) return res;
2769 }
2770
2771 uint8_t flashMode = ANDROID_FLASH_OFF;
2772 uint8_t aeMode;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002773 switch (params.flashMode) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002774 case Parameters::FLASH_MODE_OFF:
2775 aeMode = ANDROID_CONTROL_AE_ON; break;
2776 case Parameters::FLASH_MODE_AUTO:
2777 aeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH; break;
2778 case Parameters::FLASH_MODE_ON:
2779 aeMode = ANDROID_CONTROL_AE_ON_ALWAYS_FLASH; break;
2780 case Parameters::FLASH_MODE_TORCH:
2781 aeMode = ANDROID_CONTROL_AE_ON;
2782 flashMode = ANDROID_FLASH_TORCH;
2783 break;
2784 case Parameters::FLASH_MODE_RED_EYE:
2785 aeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE; break;
2786 default:
2787 ALOGE("%s: Camera %d: Unknown flash mode %d", __FUNCTION__,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002788 mCameraId, params.flashMode);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002789 return BAD_VALUE;
2790 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002791 if (params.autoExposureLock) aeMode = ANDROID_CONTROL_AE_LOCKED;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002792
2793 res = updateEntry(request,
2794 ANDROID_FLASH_MODE, &flashMode, 1);
2795 if (res != OK) return res;
2796 res = updateEntry(request,
2797 ANDROID_CONTROL_AE_MODE, &aeMode, 1);
2798 if (res != OK) return res;
2799
2800 float focusDistance = 0; // infinity focus in diopters
2801 uint8_t focusMode;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002802 switch (params.focusMode) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002803 case Parameters::FOCUS_MODE_AUTO:
2804 case Parameters::FOCUS_MODE_MACRO:
2805 case Parameters::FOCUS_MODE_CONTINUOUS_VIDEO:
2806 case Parameters::FOCUS_MODE_CONTINUOUS_PICTURE:
2807 case Parameters::FOCUS_MODE_EDOF:
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002808 focusMode = params.focusMode;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002809 break;
2810 case Parameters::FOCUS_MODE_INFINITY:
2811 case Parameters::FOCUS_MODE_FIXED:
2812 focusMode = ANDROID_CONTROL_AF_OFF;
2813 break;
2814 default:
2815 ALOGE("%s: Camera %d: Unknown focus mode %d", __FUNCTION__,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002816 mCameraId, params.focusMode);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002817 return BAD_VALUE;
2818 }
2819 res = updateEntry(request,
2820 ANDROID_LENS_FOCUS_DISTANCE, &focusDistance, 1);
2821 if (res != OK) return res;
2822 res = updateEntry(request,
2823 ANDROID_CONTROL_AF_MODE, &focusMode, 1);
2824 if (res != OK) return res;
2825
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002826 size_t focusingAreasSize = params.focusingAreas.size() * 5;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002827 int32_t *focusingAreas = new int32_t[focusingAreasSize];
2828 for (size_t i = 0; i < focusingAreasSize; i += 5) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002829 focusingAreas[i + 0] = params.focusingAreas[i].left;
2830 focusingAreas[i + 1] = params.focusingAreas[i].top;
2831 focusingAreas[i + 2] = params.focusingAreas[i].right;
2832 focusingAreas[i + 3] = params.focusingAreas[i].bottom;
2833 focusingAreas[i + 4] = params.focusingAreas[i].weight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002834 }
2835 res = updateEntry(request,
2836 ANDROID_CONTROL_AF_REGIONS, focusingAreas,focusingAreasSize);
2837 if (res != OK) return res;
2838 delete[] focusingAreas;
2839
2840 res = updateEntry(request,
2841 ANDROID_CONTROL_AE_EXP_COMPENSATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002842 &params.exposureCompensation, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002843 if (res != OK) return res;
2844
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002845 size_t meteringAreasSize = params.meteringAreas.size() * 5;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002846 int32_t *meteringAreas = new int32_t[meteringAreasSize];
2847 for (size_t i = 0; i < meteringAreasSize; i += 5) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002848 meteringAreas[i + 0] = params.meteringAreas[i].left;
2849 meteringAreas[i + 1] = params.meteringAreas[i].top;
2850 meteringAreas[i + 2] = params.meteringAreas[i].right;
2851 meteringAreas[i + 3] = params.meteringAreas[i].bottom;
2852 meteringAreas[i + 4] = params.meteringAreas[i].weight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002853 }
2854 res = updateEntry(request,
2855 ANDROID_CONTROL_AE_REGIONS, meteringAreas, meteringAreasSize);
2856 if (res != OK) return res;
2857
2858 res = updateEntry(request,
2859 ANDROID_CONTROL_AWB_REGIONS, meteringAreas, meteringAreasSize);
2860 if (res != OK) return res;
2861 delete[] meteringAreas;
2862
2863 // Need to convert zoom index into a crop rectangle. The rectangle is
2864 // chosen to maximize its area on the sensor
2865
2866 camera_metadata_entry_t maxDigitalZoom =
2867 staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM);
2868 float zoomIncrement = (maxDigitalZoom.data.f[0] - 1) /
2869 (NUM_ZOOM_STEPS-1);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002870 float zoomRatio = 1 + zoomIncrement * params.zoom;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002871
2872 camera_metadata_entry_t activePixelArraySize =
2873 staticInfo(ANDROID_SENSOR_ACTIVE_ARRAY_SIZE, 2, 2);
2874 int32_t arrayWidth = activePixelArraySize.data.i32[0];
2875 int32_t arrayHeight = activePixelArraySize.data.i32[1];
2876 float zoomLeft, zoomTop, zoomWidth, zoomHeight;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002877 if (params.previewWidth >= params.previewHeight) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002878 zoomWidth = arrayWidth / zoomRatio;
2879 zoomHeight = zoomWidth *
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002880 params.previewHeight / params.previewWidth;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002881 } else {
2882 zoomHeight = arrayHeight / zoomRatio;
2883 zoomWidth = zoomHeight *
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002884 params.previewWidth / params.previewHeight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002885 }
2886 zoomLeft = (arrayWidth - zoomWidth) / 2;
2887 zoomTop = (arrayHeight - zoomHeight) / 2;
2888
2889 int32_t cropRegion[3] = { zoomLeft, zoomTop, zoomWidth };
2890 res = updateEntry(request,
2891 ANDROID_SCALER_CROP_REGION, cropRegion, 3);
2892 if (res != OK) return res;
2893
2894 // TODO: Decide how to map recordingHint, or whether just to ignore it
2895
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002896 uint8_t vstabMode = params.videoStabilization ?
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002897 ANDROID_CONTROL_VIDEO_STABILIZATION_ON :
2898 ANDROID_CONTROL_VIDEO_STABILIZATION_OFF;
2899 res = updateEntry(request,
2900 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
2901 &vstabMode, 1);
2902 if (res != OK) return res;
2903
2904 return OK;
2905}
2906
2907status_t Camera2Client::updateEntry(camera_metadata_t *buffer,
2908 uint32_t tag, const void *data, size_t data_count) {
2909 camera_metadata_entry_t entry;
2910 status_t res;
2911 res = find_camera_metadata_entry(buffer, tag, &entry);
2912 if (res == NAME_NOT_FOUND) {
2913 res = add_camera_metadata_entry(buffer,
2914 tag, data, data_count);
2915 } else if (res == OK) {
2916 res = update_camera_metadata_entry(buffer,
2917 entry.index, data, data_count, NULL);
2918 }
2919
2920 if (res != OK) {
2921 ALOGE("%s: Unable to update metadata entry %s.%s (%x): %s (%d)",
2922 __FUNCTION__, get_camera_metadata_section_name(tag),
2923 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
2924 }
2925 return res;
2926}
2927
2928status_t Camera2Client::deleteEntry(camera_metadata_t *buffer, uint32_t tag) {
2929 camera_metadata_entry_t entry;
2930 status_t res;
2931 res = find_camera_metadata_entry(buffer, tag, &entry);
2932 if (res == NAME_NOT_FOUND) {
2933 return OK;
2934 } else if (res != OK) {
2935 ALOGE("%s: Error looking for entry %s.%s (%x): %s %d",
2936 __FUNCTION__,
2937 get_camera_metadata_section_name(tag),
2938 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
2939 return res;
2940 }
2941 res = delete_camera_metadata_entry(buffer, entry.index);
2942 if (res != OK) {
2943 ALOGE("%s: Error deleting entry %s.%s (%x): %s %d",
2944 __FUNCTION__,
2945 get_camera_metadata_section_name(tag),
2946 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
2947 }
2948 return res;
2949}
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002950
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07002951int Camera2Client::formatStringToEnum(const char *format) {
2952 return
2953 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422SP) ?
2954 HAL_PIXEL_FORMAT_YCbCr_422_SP : // NV16
2955 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420SP) ?
2956 HAL_PIXEL_FORMAT_YCrCb_420_SP : // NV21
2957 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422I) ?
2958 HAL_PIXEL_FORMAT_YCbCr_422_I : // YUY2
2959 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420P) ?
2960 HAL_PIXEL_FORMAT_YV12 : // YV12
2961 !strcmp(format, CameraParameters::PIXEL_FORMAT_RGB565) ?
2962 HAL_PIXEL_FORMAT_RGB_565 : // RGB565
2963 !strcmp(format, CameraParameters::PIXEL_FORMAT_RGBA8888) ?
2964 HAL_PIXEL_FORMAT_RGBA_8888 : // RGB8888
2965 !strcmp(format, CameraParameters::PIXEL_FORMAT_BAYER_RGGB) ?
2966 HAL_PIXEL_FORMAT_RAW_SENSOR : // Raw sensor data
2967 -1;
2968}
2969
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002970const char* Camera2Client::formatEnumToString(int format) {
2971 const char *fmt;
2972 switch(format) {
2973 case HAL_PIXEL_FORMAT_YCbCr_422_SP: // NV16
2974 fmt = CameraParameters::PIXEL_FORMAT_YUV422SP;
2975 break;
2976 case HAL_PIXEL_FORMAT_YCrCb_420_SP: // NV21
2977 fmt = CameraParameters::PIXEL_FORMAT_YUV420SP;
2978 break;
2979 case HAL_PIXEL_FORMAT_YCbCr_422_I: // YUY2
2980 fmt = CameraParameters::PIXEL_FORMAT_YUV422I;
2981 break;
2982 case HAL_PIXEL_FORMAT_YV12: // YV12
2983 fmt = CameraParameters::PIXEL_FORMAT_YUV420P;
2984 break;
2985 case HAL_PIXEL_FORMAT_RGB_565: // RGB565
2986 fmt = CameraParameters::PIXEL_FORMAT_RGB565;
2987 break;
2988 case HAL_PIXEL_FORMAT_RGBA_8888: // RGBA8888
2989 fmt = CameraParameters::PIXEL_FORMAT_RGBA8888;
2990 break;
2991 case HAL_PIXEL_FORMAT_RAW_SENSOR:
2992 ALOGW("Raw sensor preview format requested.");
2993 fmt = CameraParameters::PIXEL_FORMAT_BAYER_RGGB;
2994 break;
2995 default:
2996 ALOGE("%s: Unknown preview format: %x",
2997 __FUNCTION__, format);
2998 fmt = NULL;
2999 break;
3000 }
3001 return fmt;
3002}
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07003003
3004int Camera2Client::wbModeStringToEnum(const char *wbMode) {
3005 return
3006 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_AUTO) ?
3007 ANDROID_CONTROL_AWB_AUTO :
3008 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_INCANDESCENT) ?
3009 ANDROID_CONTROL_AWB_INCANDESCENT :
3010 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_FLUORESCENT) ?
3011 ANDROID_CONTROL_AWB_FLUORESCENT :
3012 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT) ?
3013 ANDROID_CONTROL_AWB_WARM_FLUORESCENT :
3014 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_DAYLIGHT) ?
3015 ANDROID_CONTROL_AWB_DAYLIGHT :
3016 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT) ?
3017 ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT :
3018 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_TWILIGHT) ?
3019 ANDROID_CONTROL_AWB_TWILIGHT :
3020 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_SHADE) ?
3021 ANDROID_CONTROL_AWB_SHADE :
3022 -1;
3023}
3024
3025int Camera2Client::effectModeStringToEnum(const char *effectMode) {
3026 return
3027 !strcmp(effectMode, CameraParameters::EFFECT_NONE) ?
3028 ANDROID_CONTROL_EFFECT_OFF :
3029 !strcmp(effectMode, CameraParameters::EFFECT_MONO) ?
3030 ANDROID_CONTROL_EFFECT_MONO :
3031 !strcmp(effectMode, CameraParameters::EFFECT_NEGATIVE) ?
3032 ANDROID_CONTROL_EFFECT_NEGATIVE :
3033 !strcmp(effectMode, CameraParameters::EFFECT_SOLARIZE) ?
3034 ANDROID_CONTROL_EFFECT_SOLARIZE :
3035 !strcmp(effectMode, CameraParameters::EFFECT_SEPIA) ?
3036 ANDROID_CONTROL_EFFECT_SEPIA :
3037 !strcmp(effectMode, CameraParameters::EFFECT_POSTERIZE) ?
3038 ANDROID_CONTROL_EFFECT_POSTERIZE :
3039 !strcmp(effectMode, CameraParameters::EFFECT_WHITEBOARD) ?
3040 ANDROID_CONTROL_EFFECT_WHITEBOARD :
3041 !strcmp(effectMode, CameraParameters::EFFECT_BLACKBOARD) ?
3042 ANDROID_CONTROL_EFFECT_BLACKBOARD :
3043 !strcmp(effectMode, CameraParameters::EFFECT_AQUA) ?
3044 ANDROID_CONTROL_EFFECT_AQUA :
3045 -1;
3046}
3047
3048int Camera2Client::abModeStringToEnum(const char *abMode) {
3049 return
3050 !strcmp(abMode, CameraParameters::ANTIBANDING_AUTO) ?
3051 ANDROID_CONTROL_AE_ANTIBANDING_AUTO :
3052 !strcmp(abMode, CameraParameters::ANTIBANDING_OFF) ?
3053 ANDROID_CONTROL_AE_ANTIBANDING_OFF :
3054 !strcmp(abMode, CameraParameters::ANTIBANDING_50HZ) ?
3055 ANDROID_CONTROL_AE_ANTIBANDING_50HZ :
3056 !strcmp(abMode, CameraParameters::ANTIBANDING_60HZ) ?
3057 ANDROID_CONTROL_AE_ANTIBANDING_60HZ :
3058 -1;
3059}
3060
3061int Camera2Client::sceneModeStringToEnum(const char *sceneMode) {
3062 return
3063 !strcmp(sceneMode, CameraParameters::SCENE_MODE_AUTO) ?
3064 ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED :
3065 !strcmp(sceneMode, CameraParameters::SCENE_MODE_ACTION) ?
3066 ANDROID_CONTROL_SCENE_MODE_ACTION :
3067 !strcmp(sceneMode, CameraParameters::SCENE_MODE_PORTRAIT) ?
3068 ANDROID_CONTROL_SCENE_MODE_PORTRAIT :
3069 !strcmp(sceneMode, CameraParameters::SCENE_MODE_LANDSCAPE) ?
3070 ANDROID_CONTROL_SCENE_MODE_LANDSCAPE :
3071 !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT) ?
3072 ANDROID_CONTROL_SCENE_MODE_NIGHT :
3073 !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT_PORTRAIT) ?
3074 ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT :
3075 !strcmp(sceneMode, CameraParameters::SCENE_MODE_THEATRE) ?
3076 ANDROID_CONTROL_SCENE_MODE_THEATRE :
3077 !strcmp(sceneMode, CameraParameters::SCENE_MODE_BEACH) ?
3078 ANDROID_CONTROL_SCENE_MODE_BEACH :
3079 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SNOW) ?
3080 ANDROID_CONTROL_SCENE_MODE_SNOW :
3081 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SUNSET) ?
3082 ANDROID_CONTROL_SCENE_MODE_SUNSET :
3083 !strcmp(sceneMode, CameraParameters::SCENE_MODE_STEADYPHOTO) ?
3084 ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO :
3085 !strcmp(sceneMode, CameraParameters::SCENE_MODE_FIREWORKS) ?
3086 ANDROID_CONTROL_SCENE_MODE_FIREWORKS :
3087 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SPORTS) ?
3088 ANDROID_CONTROL_SCENE_MODE_SPORTS :
3089 !strcmp(sceneMode, CameraParameters::SCENE_MODE_PARTY) ?
3090 ANDROID_CONTROL_SCENE_MODE_PARTY :
3091 !strcmp(sceneMode, CameraParameters::SCENE_MODE_CANDLELIGHT) ?
3092 ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT :
3093 !strcmp(sceneMode, CameraParameters::SCENE_MODE_BARCODE) ?
3094 ANDROID_CONTROL_SCENE_MODE_BARCODE:
3095 -1;
3096}
3097
3098Camera2Client::Parameters::flashMode_t Camera2Client::flashModeStringToEnum(
3099 const char *flashMode) {
3100 return
3101 !strcmp(flashMode, CameraParameters::FLASH_MODE_OFF) ?
3102 Parameters::FLASH_MODE_OFF :
3103 !strcmp(flashMode, CameraParameters::FLASH_MODE_AUTO) ?
3104 Parameters::FLASH_MODE_AUTO :
3105 !strcmp(flashMode, CameraParameters::FLASH_MODE_ON) ?
3106 Parameters::FLASH_MODE_ON :
3107 !strcmp(flashMode, CameraParameters::FLASH_MODE_RED_EYE) ?
3108 Parameters::FLASH_MODE_RED_EYE :
3109 !strcmp(flashMode, CameraParameters::FLASH_MODE_TORCH) ?
3110 Parameters::FLASH_MODE_TORCH :
3111 Parameters::FLASH_MODE_INVALID;
3112}
3113
3114Camera2Client::Parameters::focusMode_t Camera2Client::focusModeStringToEnum(
3115 const char *focusMode) {
3116 return
3117 !strcmp(focusMode, CameraParameters::FOCUS_MODE_AUTO) ?
3118 Parameters::FOCUS_MODE_AUTO :
3119 !strcmp(focusMode, CameraParameters::FOCUS_MODE_INFINITY) ?
3120 Parameters::FOCUS_MODE_INFINITY :
3121 !strcmp(focusMode, CameraParameters::FOCUS_MODE_MACRO) ?
3122 Parameters::FOCUS_MODE_MACRO :
3123 !strcmp(focusMode, CameraParameters::FOCUS_MODE_FIXED) ?
3124 Parameters::FOCUS_MODE_FIXED :
3125 !strcmp(focusMode, CameraParameters::FOCUS_MODE_EDOF) ?
3126 Parameters::FOCUS_MODE_EDOF :
3127 !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO) ?
3128 Parameters::FOCUS_MODE_CONTINUOUS_VIDEO :
3129 !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE) ?
3130 Parameters::FOCUS_MODE_CONTINUOUS_PICTURE :
3131 Parameters::FOCUS_MODE_INVALID;
3132}
3133
3134status_t Camera2Client::parseAreas(const char *areasCStr,
3135 Vector<Parameters::Area> *areas) {
3136 static const size_t NUM_FIELDS = 5;
3137 areas->clear();
3138 if (areasCStr == NULL) {
3139 // If no key exists, use default (0,0,0,0,0)
3140 areas->push();
3141 return OK;
3142 }
3143 String8 areasStr(areasCStr);
3144 ssize_t areaStart = areasStr.find("(", 0) + 1;
3145 while (areaStart != 0) {
3146 const char* area = areasStr.string() + areaStart;
3147 char *numEnd;
3148 int vals[NUM_FIELDS];
3149 for (size_t i = 0; i < NUM_FIELDS; i++) {
3150 errno = 0;
3151 vals[i] = strtol(area, &numEnd, 10);
3152 if (errno || numEnd == area) return BAD_VALUE;
3153 area = numEnd + 1;
3154 }
3155 areas->push(Parameters::Area(
3156 vals[0], vals[1], vals[2], vals[3], vals[4]) );
3157 areaStart = areasStr.find("(", areaStart) + 1;
3158 }
3159 return OK;
3160}
3161
3162status_t Camera2Client::validateAreas(const Vector<Parameters::Area> &areas,
3163 size_t maxRegions) {
3164 // Definition of valid area can be found in
3165 // include/camera/CameraParameters.h
3166 if (areas.size() == 0) return BAD_VALUE;
3167 if (areas.size() == 1) {
3168 if (areas[0].left == 0 &&
3169 areas[0].top == 0 &&
3170 areas[0].right == 0 &&
3171 areas[0].bottom == 0 &&
3172 areas[0].weight == 0) {
3173 // Single (0,0,0,0,0) entry is always valid (== driver decides)
3174 return OK;
3175 }
3176 }
3177 if (areas.size() > maxRegions) {
3178 ALOGE("%s: Too many areas requested: %d",
3179 __FUNCTION__, areas.size());
3180 return BAD_VALUE;
3181 }
3182
3183 for (Vector<Parameters::Area>::const_iterator a = areas.begin();
3184 a != areas.end(); a++) {
3185 if (a->weight < 1 || a->weight > 1000) return BAD_VALUE;
3186 if (a->left < -1000 || a->left > 1000) return BAD_VALUE;
3187 if (a->top < -1000 || a->top > 1000) return BAD_VALUE;
3188 if (a->right < -1000 || a->right > 1000) return BAD_VALUE;
3189 if (a->bottom < -1000 || a->bottom > 1000) return BAD_VALUE;
3190 if (a->left >= a->right) return BAD_VALUE;
3191 if (a->top >= a->bottom) return BAD_VALUE;
3192 }
3193 return OK;
3194}
3195
3196bool Camera2Client::boolFromString(const char *boolStr) {
3197 return !boolStr ? false :
3198 !strcmp(boolStr, CameraParameters::TRUE) ? true :
3199 false;
3200}
3201
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07003202int Camera2Client::degToTransform(int degrees, bool mirror) {
3203 if (!mirror) {
3204 if (degrees == 0) return 0;
3205 else if (degrees == 90) return HAL_TRANSFORM_ROT_90;
3206 else if (degrees == 180) return HAL_TRANSFORM_ROT_180;
3207 else if (degrees == 270) return HAL_TRANSFORM_ROT_270;
3208 } else { // Do mirror (horizontal flip)
3209 if (degrees == 0) { // FLIP_H and ROT_0
3210 return HAL_TRANSFORM_FLIP_H;
3211 } else if (degrees == 90) { // FLIP_H and ROT_90
3212 return HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90;
3213 } else if (degrees == 180) { // FLIP_H and ROT_180
3214 return HAL_TRANSFORM_FLIP_V;
3215 } else if (degrees == 270) { // FLIP_H and ROT_270
3216 return HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90;
3217 }
3218 }
3219 ALOGE("%s: Bad input: %d", __FUNCTION__, degrees);
3220 return -1;
3221}
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07003222
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07003223} // namespace android