blob: cd74e6d1c0e3d18b13306ac57004c7b841202766 [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),
James Dong983cf232012-08-01 16:39:55 -070061 mRecordingRequest(NULL),
62 mRecordingHeapCount(kDefaultRecordingHeapCount)
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070063{
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070064 ATRACE_CALL();
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070065
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070066 mDevice = new Camera2Device(cameraId);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070067}
68
Eino-Ville Talvala3a609142012-07-31 14:36:26 -070069status_t Camera2Client::checkPid(const char* checkLocation) const {
70 int callingPid = getCallingPid();
71 if (callingPid == mClientPid) return NO_ERROR;
72
73 ALOGE("%s: attempt to use a locked camera from a different process"
74 " (old pid %d, new pid %d)", checkLocation, mClientPid, callingPid);
75 return PERMISSION_DENIED;
76}
77
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070078status_t Camera2Client::initialize(camera_module_t *module)
79{
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070080 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -070081 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070082 status_t res;
83
84 res = mDevice->initialize(module);
85 if (res != OK) {
86 ALOGE("%s: Camera %d: unable to initialize device: %s (%d)",
87 __FUNCTION__, mCameraId, strerror(-res), res);
88 return NO_INIT;
89 }
90
91 res = buildDefaultParameters();
92 if (res != OK) {
93 ALOGE("%s: Camera %d: unable to build defaults: %s (%d)",
94 __FUNCTION__, mCameraId, strerror(-res), res);
95 return NO_INIT;
96 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -070097
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070098 if (gLogLevel >= 1) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -070099 LockedParameters::Key k(mParameters);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700100 ALOGD("%s: Default parameters converted from camera %d:", __FUNCTION__,
101 mCameraId);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700102 ALOGD("%s", k.mParameters.paramsFlattened.string());
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700103 }
104
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700105 mState = STOPPED;
106
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700107 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700108}
109
110Camera2Client::~Camera2Client() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700111 ATRACE_CALL();
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700112 ALOGV("%s: Camera %d: Shutting down", __FUNCTION__, mCameraId);
113
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700114 mDestructionStarted = true;
115
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700116 // Rewrite mClientPid to allow shutdown by CameraService
117 mClientPid = getCallingPid();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700118 disconnect();
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 Talvala36cdfb12012-08-02 17:34:15 -0700356 stopPreviewL();
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 Talvala36cdfb12012-08-02 17:34:15 -0700455 return setPreviewWindowL(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 Talvala36cdfb12012-08-02 17:34:15 -0700472 return setPreviewWindowL(binder, window);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700473}
474
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700475status_t Camera2Client::setPreviewWindowL(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 Talvala36cdfb12012-08-02 17:34:15 -0700527 return startPreviewL();
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 Talvala36cdfb12012-08-02 17:34:15 -0700546 return startPreviewL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700547}
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700548
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700549status_t Camera2Client::startPreviewL() {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700550 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 Talvala36cdfb12012-08-02 17:34:15 -0700615 stopPreviewL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700616}
617
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700618void Camera2Client::stopPreviewL() {
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700619 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:
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700686 res = startPreviewL();
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700687 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);
James Dong8da4cd72012-08-04 19:58:07 -0700795
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700796 if ( checkPid(__FUNCTION__) != OK) return false;
797
James Dong8da4cd72012-08-04 19:58:07 -0700798 return recordingEnabledL();
799}
800
801bool Camera2Client::recordingEnabledL() {
802 ATRACE_CALL();
803
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700804 return (mState == RECORD || mState == VIDEO_SNAPSHOT);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700805}
806
807void Camera2Client::releaseRecordingFrame(const sp<IMemory>& mem) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700808 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700809 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700810 status_t res;
811 if ( checkPid(__FUNCTION__) != OK) return;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700812 // Make sure this is for the current heap
813 ssize_t offset;
814 size_t size;
815 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
816 if (heap->getHeapID() != mRecordingHeap->mHeap->getHeapID()) {
817 ALOGW("%s: Camera %d: Mismatched heap ID, ignoring release "
818 "(got %x, expected %x)", __FUNCTION__, mCameraId,
819 heap->getHeapID(), mRecordingHeap->mHeap->getHeapID());
820 return;
821 }
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700822 uint8_t *data = (uint8_t*)heap->getBase() + offset;
823 uint32_t type = *(uint32_t*)data;
824 if (type != kMetadataBufferTypeGrallocSource) {
825 ALOGE("%s: Camera %d: Recording frame type invalid (got %x, expected %x)",
826 __FUNCTION__, mCameraId, type, kMetadataBufferTypeGrallocSource);
827 return;
828 }
829 buffer_handle_t imgBuffer = *(buffer_handle_t*)(data + 4);
830 ALOGV("%s: Camera %d: Freeing buffer_handle_t %p", __FUNCTION__, mCameraId,
Eino-Ville Talvala803cbf62012-07-25 15:23:36 -0700831 imgBuffer);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700832 res = mRecordingConsumer->freeBuffer(imgBuffer);
833 if (res != OK) {
834 ALOGE("%s: Camera %d: Unable to free recording frame (buffer_handle_t: %p):"
835 "%s (%d)",
836 __FUNCTION__, mCameraId, imgBuffer, strerror(-res), res);
837 return;
838 }
839
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700840 mRecordingHeapFree++;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700841}
842
843status_t Camera2Client::autoFocus() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700844 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700845 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700846 status_t res;
847 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
848
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700849 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700850}
851
852status_t Camera2Client::cancelAutoFocus() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700853 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700854 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700855 status_t res;
856 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
857
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700858 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700859}
860
861status_t Camera2Client::takePicture(int msgType) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700862 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700863 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700864 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700865 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700866
867 switch (mState) {
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700868 case DISCONNECTED:
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700869 case STOPPED:
870 case WAITING_FOR_PREVIEW_WINDOW:
871 ALOGE("%s: Camera %d: Cannot take picture without preview enabled",
872 __FUNCTION__, mCameraId);
873 return INVALID_OPERATION;
874 case PREVIEW:
875 case RECORD:
876 // Good to go for takePicture
877 break;
878 case STILL_CAPTURE:
879 case VIDEO_SNAPSHOT:
880 ALOGE("%s: Camera %d: Already taking a picture",
881 __FUNCTION__, mCameraId);
882 return INVALID_OPERATION;
883 }
884
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700885 LockedParameters::Key k(mParameters);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700886
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700887 res = updateCaptureStream(k.mParameters);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700888 if (res != OK) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700889 ALOGE("%s: Camera %d: Can't set up still image stream: %s (%d)",
890 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700891 return res;
892 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700893
894 if (mCaptureRequest == NULL) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700895 res = updateCaptureRequest(k.mParameters);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700896 if (res != OK) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700897 ALOGE("%s: Camera %d: Can't create still image capture request: "
898 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700899 return res;
900 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700901 }
902
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700903 camera_metadata_entry_t outputStreams;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700904 if (mState == PREVIEW) {
905 uint8_t streamIds[2] = { mPreviewStreamId, mCaptureStreamId };
906 res = updateEntry(mCaptureRequest, ANDROID_REQUEST_OUTPUT_STREAMS,
907 &streamIds, 2);
908 } else if (mState == RECORD) {
909 uint8_t streamIds[3] = { mPreviewStreamId, mRecordingStreamId,
910 mCaptureStreamId };
911 res = updateEntry(mCaptureRequest, ANDROID_REQUEST_OUTPUT_STREAMS,
912 &streamIds, 3);
913 }
914
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700915 if (res != OK) {
916 ALOGE("%s: Camera %d: Unable to set up still image capture request: "
917 "%s (%d)",
918 __FUNCTION__, mCameraId, strerror(-res), res);
919 return res;
920 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700921 res = sort_camera_metadata(mCaptureRequest);
922 if (res != OK) {
923 ALOGE("%s: Camera %d: Unable to sort capture request: %s (%d)",
924 __FUNCTION__, mCameraId, strerror(-res), res);
925 return res;
926 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700927
928 camera_metadata_t *captureCopy = clone_camera_metadata(mCaptureRequest);
929 if (captureCopy == NULL) {
930 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device",
931 __FUNCTION__, mCameraId);
932 return NO_MEMORY;
933 }
934
935 if (mState == PREVIEW) {
936 res = mDevice->setStreamingRequest(NULL);
937 if (res != OK) {
938 ALOGE("%s: Camera %d: Unable to stop preview for still capture: "
939 "%s (%d)",
940 __FUNCTION__, mCameraId, strerror(-res), res);
941 return res;
942 }
943 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700944 // TODO: Capture should be atomic with setStreamingRequest here
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700945 res = mDevice->capture(captureCopy);
946 if (res != OK) {
947 ALOGE("%s: Camera %d: Unable to submit still image capture request: "
948 "%s (%d)",
949 __FUNCTION__, mCameraId, strerror(-res), res);
950 return res;
951 }
952
953 switch (mState) {
954 case PREVIEW:
955 mState = STILL_CAPTURE;
956 break;
957 case RECORD:
958 mState = VIDEO_SNAPSHOT;
959 break;
960 default:
961 ALOGE("%s: Camera %d: Unknown state for still capture!",
962 __FUNCTION__, mCameraId);
963 return INVALID_OPERATION;
964 }
965
966 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700967}
968
969status_t Camera2Client::setParameters(const String8& params) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700970 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700971 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700972 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700973 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700974 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
975
976 LockedParameters::Key k(mParameters);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700977
978 CameraParameters newParams(params);
979
980 // TODO: Currently ignoring any changes to supposedly read-only
981 // parameters such as supported preview sizes, etc. Should probably
982 // produce an error if they're changed.
983
984 /** Extract and verify new parameters */
985
986 size_t i;
987
988 // PREVIEW_SIZE
989 int previewWidth, previewHeight;
990 newParams.getPreviewSize(&previewWidth, &previewHeight);
991
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700992 if (previewWidth != k.mParameters.previewWidth ||
993 previewHeight != k.mParameters.previewHeight) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700994 if (mState >= PREVIEW) {
995 ALOGE("%s: Preview size cannot be updated when preview "
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700996 "is active! (Currently %d x %d, requested %d x %d",
997 __FUNCTION__,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700998 k.mParameters.previewWidth, k.mParameters.previewHeight,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700999 previewWidth, previewHeight);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001000 return BAD_VALUE;
1001 }
1002 camera_metadata_entry_t availablePreviewSizes =
1003 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
1004 for (i = 0; i < availablePreviewSizes.count; i += 2 ) {
1005 if (availablePreviewSizes.data.i32[i] == previewWidth &&
1006 availablePreviewSizes.data.i32[i+1] == previewHeight) break;
1007 }
1008 if (i == availablePreviewSizes.count) {
1009 ALOGE("%s: Requested preview size %d x %d is not supported",
1010 __FUNCTION__, previewWidth, previewHeight);
1011 return BAD_VALUE;
1012 }
1013 }
1014
1015 // PREVIEW_FPS_RANGE
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001016 int previewFpsRange[2];
1017 int previewFps = 0;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001018 bool fpsRangeChanged = false;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001019 newParams.getPreviewFpsRange(&previewFpsRange[0], &previewFpsRange[1]);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001020 if (previewFpsRange[0] != k.mParameters.previewFpsRange[0] ||
1021 previewFpsRange[1] != k.mParameters.previewFpsRange[1]) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001022 fpsRangeChanged = true;
1023 camera_metadata_entry_t availablePreviewFpsRanges =
1024 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
1025 for (i = 0; i < availablePreviewFpsRanges.count; i += 2) {
1026 if ((availablePreviewFpsRanges.data.i32[i] ==
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001027 previewFpsRange[0]) &&
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001028 (availablePreviewFpsRanges.data.i32[i+1] ==
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001029 previewFpsRange[1]) ) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001030 break;
1031 }
1032 }
1033 if (i == availablePreviewFpsRanges.count) {
1034 ALOGE("%s: Requested preview FPS range %d - %d is not supported",
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001035 __FUNCTION__, previewFpsRange[0], previewFpsRange[1]);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001036 return BAD_VALUE;
1037 }
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001038 previewFps = previewFpsRange[0];
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001039 }
1040
1041 // PREVIEW_FORMAT
1042 int previewFormat = formatStringToEnum(newParams.getPreviewFormat());
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001043 if (previewFormat != k.mParameters.previewFormat) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001044 if (mState >= PREVIEW) {
1045 ALOGE("%s: Preview format cannot be updated when preview "
1046 "is active!", __FUNCTION__);
1047 return BAD_VALUE;
1048 }
1049 camera_metadata_entry_t availableFormats =
1050 staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
1051 for (i = 0; i < availableFormats.count; i++) {
1052 if (availableFormats.data.i32[i] == previewFormat) break;
1053 }
1054 if (i == availableFormats.count) {
1055 ALOGE("%s: Requested preview format %s (0x%x) is not supported",
1056 __FUNCTION__, newParams.getPreviewFormat(), previewFormat);
1057 return BAD_VALUE;
1058 }
1059 }
1060
1061 // PREVIEW_FRAME_RATE
1062 // Deprecated, only use if the preview fps range is unchanged this time.
1063 // The single-value FPS is the same as the minimum of the range.
1064 if (!fpsRangeChanged) {
1065 previewFps = newParams.getPreviewFrameRate();
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001066 if (previewFps != k.mParameters.previewFps) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001067 camera_metadata_entry_t availableFrameRates =
1068 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
1069 for (i = 0; i < availableFrameRates.count; i+=2) {
1070 if (availableFrameRates.data.i32[i] == previewFps) break;
1071 }
1072 if (i == availableFrameRates.count) {
1073 ALOGE("%s: Requested preview frame rate %d is not supported",
1074 __FUNCTION__, previewFps);
1075 return BAD_VALUE;
1076 }
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001077 previewFpsRange[0] = availableFrameRates.data.i32[i];
1078 previewFpsRange[1] = availableFrameRates.data.i32[i+1];
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001079 }
1080 }
1081
1082 // PICTURE_SIZE
1083 int pictureWidth, pictureHeight;
1084 newParams.getPictureSize(&pictureWidth, &pictureHeight);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001085 if (pictureWidth == k.mParameters.pictureWidth ||
1086 pictureHeight == k.mParameters.pictureHeight) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001087 camera_metadata_entry_t availablePictureSizes =
1088 staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES);
1089 for (i = 0; i < availablePictureSizes.count; i+=2) {
1090 if (availablePictureSizes.data.i32[i] == pictureWidth &&
1091 availablePictureSizes.data.i32[i+1] == pictureHeight) break;
1092 }
1093 if (i == availablePictureSizes.count) {
1094 ALOGE("%s: Requested picture size %d x %d is not supported",
1095 __FUNCTION__, pictureWidth, pictureHeight);
1096 return BAD_VALUE;
1097 }
1098 }
1099
1100 // JPEG_THUMBNAIL_WIDTH/HEIGHT
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001101 int jpegThumbSize[2];
1102 jpegThumbSize[0] =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001103 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001104 jpegThumbSize[1] =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001105 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001106 if (jpegThumbSize[0] != k.mParameters.jpegThumbSize[0] ||
1107 jpegThumbSize[1] != k.mParameters.jpegThumbSize[1]) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001108 camera_metadata_entry_t availableJpegThumbSizes =
1109 staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES);
1110 for (i = 0; i < availableJpegThumbSizes.count; i+=2) {
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001111 if (availableJpegThumbSizes.data.i32[i] == jpegThumbSize[0] &&
1112 availableJpegThumbSizes.data.i32[i+1] == jpegThumbSize[1]) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001113 break;
1114 }
1115 }
1116 if (i == availableJpegThumbSizes.count) {
1117 ALOGE("%s: Requested JPEG thumbnail size %d x %d is not supported",
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001118 __FUNCTION__, jpegThumbSize[0], jpegThumbSize[1]);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001119 return BAD_VALUE;
1120 }
1121 }
1122
1123 // JPEG_THUMBNAIL_QUALITY
1124 int jpegThumbQuality =
1125 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
1126 if (jpegThumbQuality < 0 || jpegThumbQuality > 100) {
1127 ALOGE("%s: Requested JPEG thumbnail quality %d is not supported",
1128 __FUNCTION__, jpegThumbQuality);
1129 return BAD_VALUE;
1130 }
1131
1132 // JPEG_QUALITY
1133 int jpegQuality =
1134 newParams.getInt(CameraParameters::KEY_JPEG_QUALITY);
1135 if (jpegQuality < 0 || jpegQuality > 100) {
1136 ALOGE("%s: Requested JPEG quality %d is not supported",
1137 __FUNCTION__, jpegQuality);
1138 return BAD_VALUE;
1139 }
1140
1141 // ROTATION
1142 int jpegRotation =
1143 newParams.getInt(CameraParameters::KEY_ROTATION);
1144 if (jpegRotation != 0 &&
1145 jpegRotation != 90 &&
1146 jpegRotation != 180 &&
1147 jpegRotation != 270) {
1148 ALOGE("%s: Requested picture rotation angle %d is not supported",
1149 __FUNCTION__, jpegRotation);
1150 return BAD_VALUE;
1151 }
1152
1153 // GPS
1154 bool gpsEnabled = false;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001155 double gpsCoordinates[3] = {0,0,0};
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001156 int64_t gpsTimestamp = 0;
1157 String8 gpsProcessingMethod;
1158 const char *gpsLatStr =
1159 newParams.get(CameraParameters::KEY_GPS_LATITUDE);
1160 if (gpsLatStr != NULL) {
1161 const char *gpsLongStr =
1162 newParams.get(CameraParameters::KEY_GPS_LONGITUDE);
1163 const char *gpsAltitudeStr =
1164 newParams.get(CameraParameters::KEY_GPS_ALTITUDE);
1165 const char *gpsTimeStr =
1166 newParams.get(CameraParameters::KEY_GPS_TIMESTAMP);
1167 const char *gpsProcMethodStr =
1168 newParams.get(CameraParameters::KEY_GPS_PROCESSING_METHOD);
1169 if (gpsLongStr == NULL ||
1170 gpsAltitudeStr == NULL ||
1171 gpsTimeStr == NULL ||
1172 gpsProcMethodStr == NULL) {
1173 ALOGE("%s: Incomplete set of GPS parameters provided",
1174 __FUNCTION__);
1175 return BAD_VALUE;
1176 }
1177 char *endPtr;
1178 errno = 0;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001179 gpsCoordinates[0] = strtod(gpsLatStr, &endPtr);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001180 if (errno || endPtr == gpsLatStr) {
1181 ALOGE("%s: Malformed GPS latitude: %s", __FUNCTION__, gpsLatStr);
1182 return BAD_VALUE;
1183 }
1184 errno = 0;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001185 gpsCoordinates[1] = strtod(gpsLongStr, &endPtr);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001186 if (errno || endPtr == gpsLongStr) {
1187 ALOGE("%s: Malformed GPS longitude: %s", __FUNCTION__, gpsLongStr);
1188 return BAD_VALUE;
1189 }
1190 errno = 0;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001191 gpsCoordinates[2] = strtod(gpsAltitudeStr, &endPtr);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001192 if (errno || endPtr == gpsAltitudeStr) {
1193 ALOGE("%s: Malformed GPS altitude: %s", __FUNCTION__,
1194 gpsAltitudeStr);
1195 return BAD_VALUE;
1196 }
1197 errno = 0;
1198 gpsTimestamp = strtoll(gpsTimeStr, &endPtr, 10);
1199 if (errno || endPtr == gpsTimeStr) {
1200 ALOGE("%s: Malformed GPS timestamp: %s", __FUNCTION__, gpsTimeStr);
1201 return BAD_VALUE;
1202 }
1203 gpsProcessingMethod = gpsProcMethodStr;
1204
1205 gpsEnabled = true;
1206 }
1207
1208 // WHITE_BALANCE
1209 int wbMode = wbModeStringToEnum(
1210 newParams.get(CameraParameters::KEY_WHITE_BALANCE) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001211 if (wbMode != k.mParameters.wbMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001212 camera_metadata_entry_t availableWbModes =
1213 staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
1214 for (i = 0; i < availableWbModes.count; i++) {
1215 if (wbMode == availableWbModes.data.u8[i]) break;
1216 }
1217 if (i == availableWbModes.count) {
1218 ALOGE("%s: Requested white balance mode %s is not supported",
1219 __FUNCTION__,
1220 newParams.get(CameraParameters::KEY_WHITE_BALANCE));
1221 return BAD_VALUE;
1222 }
1223 }
1224
1225 // EFFECT
1226 int effectMode = effectModeStringToEnum(
1227 newParams.get(CameraParameters::KEY_EFFECT) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001228 if (effectMode != k.mParameters.effectMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001229 camera_metadata_entry_t availableEffectModes =
1230 staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
1231 for (i = 0; i < availableEffectModes.count; i++) {
1232 if (effectMode == availableEffectModes.data.u8[i]) break;
1233 }
1234 if (i == availableEffectModes.count) {
1235 ALOGE("%s: Requested effect mode \"%s\" is not supported",
1236 __FUNCTION__,
1237 newParams.get(CameraParameters::KEY_EFFECT) );
1238 return BAD_VALUE;
1239 }
1240 }
1241
1242 // ANTIBANDING
1243 int antibandingMode = abModeStringToEnum(
1244 newParams.get(CameraParameters::KEY_ANTIBANDING) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001245 if (antibandingMode != k.mParameters.antibandingMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001246 camera_metadata_entry_t availableAbModes =
1247 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
1248 for (i = 0; i < availableAbModes.count; i++) {
1249 if (antibandingMode == availableAbModes.data.u8[i]) break;
1250 }
1251 if (i == availableAbModes.count) {
1252 ALOGE("%s: Requested antibanding mode \"%s\" is not supported",
1253 __FUNCTION__,
1254 newParams.get(CameraParameters::KEY_ANTIBANDING));
1255 return BAD_VALUE;
1256 }
1257 }
1258
1259 // SCENE_MODE
1260 int sceneMode = sceneModeStringToEnum(
1261 newParams.get(CameraParameters::KEY_SCENE_MODE) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001262 if (sceneMode != k.mParameters.sceneMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001263 camera_metadata_entry_t availableSceneModes =
1264 staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
1265 for (i = 0; i < availableSceneModes.count; i++) {
1266 if (sceneMode == availableSceneModes.data.u8[i]) break;
1267 }
1268 if (i == availableSceneModes.count) {
1269 ALOGE("%s: Requested scene mode \"%s\" is not supported",
1270 __FUNCTION__,
1271 newParams.get(CameraParameters::KEY_SCENE_MODE));
1272 return BAD_VALUE;
1273 }
1274 }
1275
1276 // FLASH_MODE
1277 Parameters::flashMode_t flashMode = flashModeStringToEnum(
1278 newParams.get(CameraParameters::KEY_FLASH_MODE) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001279 if (flashMode != k.mParameters.flashMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001280 camera_metadata_entry_t flashAvailable =
1281 staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
1282 if (!flashAvailable.data.u8[0] &&
1283 flashMode != Parameters::FLASH_MODE_OFF) {
1284 ALOGE("%s: Requested flash mode \"%s\" is not supported: "
1285 "No flash on device", __FUNCTION__,
1286 newParams.get(CameraParameters::KEY_FLASH_MODE));
1287 return BAD_VALUE;
1288 } else if (flashMode == Parameters::FLASH_MODE_RED_EYE) {
1289 camera_metadata_entry_t availableAeModes =
1290 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
1291 for (i = 0; i < availableAeModes.count; i++) {
1292 if (flashMode == availableAeModes.data.u8[i]) break;
1293 }
1294 if (i == availableAeModes.count) {
1295 ALOGE("%s: Requested flash mode \"%s\" is not supported",
1296 __FUNCTION__,
1297 newParams.get(CameraParameters::KEY_FLASH_MODE));
1298 return BAD_VALUE;
1299 }
1300 } else if (flashMode == -1) {
1301 ALOGE("%s: Requested flash mode \"%s\" is unknown",
1302 __FUNCTION__,
1303 newParams.get(CameraParameters::KEY_FLASH_MODE));
1304 return BAD_VALUE;
1305 }
1306 }
1307
1308 // FOCUS_MODE
1309 Parameters::focusMode_t focusMode = focusModeStringToEnum(
1310 newParams.get(CameraParameters::KEY_FOCUS_MODE));
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001311 if (focusMode != k.mParameters.focusMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001312 if (focusMode != Parameters::FOCUS_MODE_FIXED) {
1313 camera_metadata_entry_t minFocusDistance =
1314 staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE);
1315 if (minFocusDistance.data.f[0] == 0) {
1316 ALOGE("%s: Requested focus mode \"%s\" is not available: "
1317 "fixed focus lens",
1318 __FUNCTION__,
1319 newParams.get(CameraParameters::KEY_FOCUS_MODE));
1320 return BAD_VALUE;
1321 } else if (focusMode != Parameters::FOCUS_MODE_INFINITY) {
1322 camera_metadata_entry_t availableFocusModes =
1323 staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
1324 for (i = 0; i < availableFocusModes.count; i++) {
1325 if (focusMode == availableFocusModes.data.u8[i]) break;
1326 }
1327 if (i == availableFocusModes.count) {
1328 ALOGE("%s: Requested focus mode \"%s\" is not supported",
1329 __FUNCTION__,
1330 newParams.get(CameraParameters::KEY_FOCUS_MODE));
1331 return BAD_VALUE;
1332 }
1333 }
1334 }
1335 }
1336
1337 // FOCUS_AREAS
1338 Vector<Parameters::Area> focusingAreas;
1339 res = parseAreas(newParams.get(CameraParameters::KEY_FOCUS_AREAS),
1340 &focusingAreas);
1341 size_t max3aRegions =
1342 (size_t)staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1).data.i32[0];
1343 if (res == OK) res = validateAreas(focusingAreas, max3aRegions);
1344 if (res != OK) {
1345 ALOGE("%s: Requested focus areas are malformed: %s",
1346 __FUNCTION__, newParams.get(CameraParameters::KEY_FOCUS_AREAS));
1347 return BAD_VALUE;
1348 }
1349
1350 // EXPOSURE_COMPENSATION
1351 int exposureCompensation =
1352 newParams.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION);
1353 camera_metadata_entry_t exposureCompensationRange =
1354 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE);
1355 if (exposureCompensation < exposureCompensationRange.data.i32[0] ||
1356 exposureCompensation > exposureCompensationRange.data.i32[1]) {
1357 ALOGE("%s: Requested exposure compensation index is out of bounds: %d",
1358 __FUNCTION__, exposureCompensation);
1359 return BAD_VALUE;
1360 }
1361
1362 // AUTO_EXPOSURE_LOCK (always supported)
1363 bool autoExposureLock = boolFromString(
1364 newParams.get(CameraParameters::KEY_AUTO_EXPOSURE_LOCK));
1365
1366 // AUTO_WHITEBALANCE_LOCK (always supported)
1367 bool autoWhiteBalanceLock = boolFromString(
1368 newParams.get(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK));
1369
1370 // METERING_AREAS
1371 Vector<Parameters::Area> meteringAreas;
1372 res = parseAreas(newParams.get(CameraParameters::KEY_METERING_AREAS),
1373 &meteringAreas);
1374 if (res == OK) res = validateAreas(focusingAreas, max3aRegions);
1375 if (res != OK) {
1376 ALOGE("%s: Requested metering areas are malformed: %s",
1377 __FUNCTION__,
1378 newParams.get(CameraParameters::KEY_METERING_AREAS));
1379 return BAD_VALUE;
1380 }
1381
1382 // ZOOM
1383 int zoom = newParams.getInt(CameraParameters::KEY_ZOOM);
1384 if (zoom < 0 || zoom > (int)NUM_ZOOM_STEPS) {
1385 ALOGE("%s: Requested zoom level %d is not supported",
1386 __FUNCTION__, zoom);
1387 return BAD_VALUE;
1388 }
1389
1390 // VIDEO_SIZE
1391 int videoWidth, videoHeight;
1392 newParams.getVideoSize(&videoWidth, &videoHeight);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001393 if (videoWidth != k.mParameters.videoWidth ||
1394 videoHeight != k.mParameters.videoHeight) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001395 if (mState == RECORD) {
1396 ALOGE("%s: Video size cannot be updated when recording is active!",
1397 __FUNCTION__);
1398 return BAD_VALUE;
1399 }
1400 camera_metadata_entry_t availableVideoSizes =
1401 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
1402 for (i = 0; i < availableVideoSizes.count; i += 2 ) {
1403 if (availableVideoSizes.data.i32[i] == videoWidth &&
1404 availableVideoSizes.data.i32[i+1] == videoHeight) break;
1405 }
1406 if (i == availableVideoSizes.count) {
1407 ALOGE("%s: Requested video size %d x %d is not supported",
1408 __FUNCTION__, videoWidth, videoHeight);
1409 return BAD_VALUE;
1410 }
1411 }
1412
1413 // RECORDING_HINT (always supported)
1414 bool recordingHint = boolFromString(
1415 newParams.get(CameraParameters::KEY_RECORDING_HINT) );
1416
1417 // VIDEO_STABILIZATION
1418 bool videoStabilization = boolFromString(
1419 newParams.get(CameraParameters::KEY_VIDEO_STABILIZATION) );
1420 camera_metadata_entry_t availableVideoStabilizationModes =
1421 staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
1422 if (videoStabilization && availableVideoStabilizationModes.count == 1) {
1423 ALOGE("%s: Video stabilization not supported", __FUNCTION__);
1424 }
1425
1426 /** Update internal parameters */
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001427
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001428 k.mParameters.previewWidth = previewWidth;
1429 k.mParameters.previewHeight = previewHeight;
1430 k.mParameters.previewFpsRange[0] = previewFpsRange[0];
1431 k.mParameters.previewFpsRange[1] = previewFpsRange[1];
1432 k.mParameters.previewFps = previewFps;
1433 k.mParameters.previewFormat = previewFormat;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001434
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001435 k.mParameters.pictureWidth = pictureWidth;
1436 k.mParameters.pictureHeight = pictureHeight;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001437
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001438 k.mParameters.jpegThumbSize[0] = jpegThumbSize[0];
1439 k.mParameters.jpegThumbSize[1] = jpegThumbSize[1];
1440 k.mParameters.jpegQuality = jpegQuality;
1441 k.mParameters.jpegThumbQuality = jpegThumbQuality;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001442
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001443 k.mParameters.gpsEnabled = gpsEnabled;
1444 k.mParameters.gpsCoordinates[0] = gpsCoordinates[0];
1445 k.mParameters.gpsCoordinates[1] = gpsCoordinates[1];
1446 k.mParameters.gpsCoordinates[2] = gpsCoordinates[2];
1447 k.mParameters.gpsTimestamp = gpsTimestamp;
1448 k.mParameters.gpsProcessingMethod = gpsProcessingMethod;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001449
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001450 k.mParameters.wbMode = wbMode;
1451 k.mParameters.effectMode = effectMode;
1452 k.mParameters.antibandingMode = antibandingMode;
1453 k.mParameters.sceneMode = sceneMode;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001454
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001455 k.mParameters.flashMode = flashMode;
1456 k.mParameters.focusMode = focusMode;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001457
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001458 k.mParameters.focusingAreas = focusingAreas;
1459 k.mParameters.exposureCompensation = exposureCompensation;
1460 k.mParameters.autoExposureLock = autoExposureLock;
1461 k.mParameters.autoWhiteBalanceLock = autoWhiteBalanceLock;
1462 k.mParameters.meteringAreas = meteringAreas;
1463 k.mParameters.zoom = zoom;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001464
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001465 k.mParameters.videoWidth = videoWidth;
1466 k.mParameters.videoHeight = videoHeight;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001467
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001468 k.mParameters.recordingHint = recordingHint;
1469 k.mParameters.videoStabilization = videoStabilization;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001470
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001471 res = updatePreviewRequest(k.mParameters);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001472 if (res != OK) {
1473 ALOGE("%s: Camera %d: Unable to update preview request: %s (%d)",
1474 __FUNCTION__, mCameraId, strerror(-res), res);
1475 return res;
1476 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001477 res = updateCaptureRequest(k.mParameters);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001478 if (res != OK) {
1479 ALOGE("%s: Camera %d: Unable to update capture request: %s (%d)",
1480 __FUNCTION__, mCameraId, strerror(-res), res);
1481 return res;
1482 }
1483
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001484 res = updateRecordingRequest(k.mParameters);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001485 if (res != OK) {
1486 ALOGE("%s: Camera %d: Unable to update recording request: %s (%d)",
1487 __FUNCTION__, mCameraId, strerror(-res), res);
1488 return res;
1489 }
1490
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001491 if (mState == PREVIEW) {
1492 res = mDevice->setStreamingRequest(mPreviewRequest);
1493 if (res != OK) {
1494 ALOGE("%s: Camera %d: Error streaming new preview request: %s (%d)",
1495 __FUNCTION__, mCameraId, strerror(-res), res);
1496 return res;
1497 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001498 } else if (mState == RECORD || mState == VIDEO_SNAPSHOT) {
1499 res = mDevice->setStreamingRequest(mRecordingRequest);
1500 if (res != OK) {
1501 ALOGE("%s: Camera %d: Error streaming new record request: %s (%d)",
1502 __FUNCTION__, mCameraId, strerror(-res), res);
1503 return res;
1504 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001505 }
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001506
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001507 k.mParameters.paramsFlattened = params;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001508
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001509 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001510}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001511
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001512String8 Camera2Client::getParameters() const {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001513 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001514 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001515 if ( checkPid(__FUNCTION__) != OK) return String8();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001516
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001517 LockedParameters::ReadKey k(mParameters);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001518
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001519 // TODO: Deal with focus distances
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001520 return k.mParameters.paramsFlattened;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001521}
1522
1523status_t Camera2Client::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001524 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001525 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001526 status_t res;
1527 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001528
1529 ALOGV("%s: Camera %d: Command %d (%d, %d)", __FUNCTION__, mCameraId,
1530 cmd, arg1, arg2);
1531
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001532 switch (cmd) {
1533 case CAMERA_CMD_START_SMOOTH_ZOOM:
1534 return commandStartSmoothZoomL();
1535 case CAMERA_CMD_STOP_SMOOTH_ZOOM:
1536 return commandStopSmoothZoomL();
1537 case CAMERA_CMD_SET_DISPLAY_ORIENTATION:
1538 return commandSetDisplayOrientationL(arg1);
1539 case CAMERA_CMD_ENABLE_SHUTTER_SOUND:
1540 return commandEnableShutterSoundL(arg1 == 1);
1541 case CAMERA_CMD_PLAY_RECORDING_SOUND:
1542 return commandPlayRecordingSoundL();
1543 case CAMERA_CMD_START_FACE_DETECTION:
1544 return commandStartFaceDetectionL(arg1);
1545 case CAMERA_CMD_STOP_FACE_DETECTION:
1546 return commandStopFaceDetectionL();
1547 case CAMERA_CMD_ENABLE_FOCUS_MOVE_MSG:
1548 return commandEnableFocusMoveMsgL(arg1 == 1);
1549 case CAMERA_CMD_PING:
1550 return commandPingL();
1551 case CAMERA_CMD_SET_VIDEO_BUFFER_COUNT:
1552 return commandSetVideoBufferCountL(arg1);
1553 default:
1554 ALOGE("%s: Unknown command %d (arguments %d, %d)",
1555 __FUNCTION__, cmd, arg1, arg2);
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001556 return BAD_VALUE;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001557 }
1558}
James Dong983cf232012-08-01 16:39:55 -07001559
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001560status_t Camera2Client::commandStartSmoothZoomL() {
1561 ALOGE("%s: Unimplemented!", __FUNCTION__);
1562 return OK;
1563}
James Dong983cf232012-08-01 16:39:55 -07001564
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001565status_t Camera2Client::commandStopSmoothZoomL() {
1566 ALOGE("%s: Unimplemented!", __FUNCTION__);
1567 return OK;
1568}
James Dong983cf232012-08-01 16:39:55 -07001569
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001570status_t Camera2Client::commandSetDisplayOrientationL(int degrees) {
1571 LockedParameters::Key k(mParameters);
1572 int transform = degToTransform(degrees,
1573 mCameraFacing == CAMERA_FACING_FRONT);
1574 if (transform == -1) {
1575 ALOGE("%s: Camera %d: Error setting %d as display orientation value",
1576 __FUNCTION__, mCameraId, degrees);
1577 return BAD_VALUE;
1578 }
1579 if (transform != k.mParameters.previewTransform &&
1580 mPreviewStreamId != NO_STREAM) {
1581 mDevice->setStreamTransform(mPreviewStreamId, transform);
1582 }
1583 k.mParameters.previewTransform = transform;
1584 return OK;
1585}
1586
1587status_t Camera2Client::commandEnableShutterSoundL(bool enable) {
1588 LockedParameters::Key k(mParameters);
1589 if (enable) {
1590 k.mParameters.playShutterSound = true;
James Dong983cf232012-08-01 16:39:55 -07001591 return OK;
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001592 }
1593
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001594 // Disabling shutter sound may not be allowed. In that case only
1595 // allow the mediaserver process to disable the sound.
1596 char value[PROPERTY_VALUE_MAX];
1597 property_get("ro.camera.sound.forced", value, "0");
1598 if (strncmp(value, "0", 2) != 0) {
1599 // Disabling shutter sound is not allowed. Deny if the current
1600 // process is not mediaserver.
1601 if (getCallingPid() != getpid()) {
1602 ALOGE("Failed to disable shutter sound. Permission denied (pid %d)",
1603 getCallingPid());
1604 return PERMISSION_DENIED;
1605 }
1606 }
1607
1608 k.mParameters.playShutterSound = false;
1609 return OK;
1610}
1611
1612status_t Camera2Client::commandPlayRecordingSoundL() {
1613 mCameraService->playSound(CameraService::SOUND_RECORDING);
1614 return OK;
1615}
1616
1617status_t Camera2Client::commandStartFaceDetectionL(int type) {
1618 ALOGE("%s: Unimplemented!", __FUNCTION__);
1619 return OK;
1620}
1621
1622status_t Camera2Client::commandStopFaceDetectionL() {
1623 ALOGE("%s: Unimplemented!", __FUNCTION__);
1624 return OK;
1625}
1626
1627status_t Camera2Client::commandEnableFocusMoveMsgL(bool enable) {
1628 ALOGE("%s: Unimplemented!", __FUNCTION__);
1629 return OK;
1630}
1631
1632status_t Camera2Client::commandPingL() {
1633 // Always ping back if access is proper and device is alive
1634 if (mState != DISCONNECTED) {
1635 return OK;
1636 } else {
1637 return NO_INIT;
1638 }
1639}
1640
1641status_t Camera2Client::commandSetVideoBufferCountL(size_t count) {
James Dong8da4cd72012-08-04 19:58:07 -07001642 if (recordingEnabledL()) {
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001643 ALOGE("%s: Camera %d: Error setting video buffer count after "
1644 "recording was started", __FUNCTION__, mCameraId);
1645 return INVALID_OPERATION;
1646 }
1647
1648 // 32 is the current upper limit on the video buffer count for BufferQueue
1649 if (count > 32) {
1650 ALOGE("%s: Camera %d: Error setting %d as video buffer count value",
1651 __FUNCTION__, mCameraId, count);
1652 return BAD_VALUE;
1653 }
1654
1655 // Need to reallocate memory for heap
1656 if (mRecordingHeapCount != count) {
1657 if (mRecordingHeap != 0) {
1658 mRecordingHeap.clear();
1659 mRecordingHeap = NULL;
1660 }
1661 mRecordingHeapCount = count;
1662 }
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001663
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001664 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001665}
1666
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001667/** Device-related methods */
1668
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -07001669void Camera2Client::notifyError(int errorCode, int arg1, int arg2) {
1670 ALOGE("Error condition %d reported by HAL, arguments %d, %d", errorCode, arg1, arg2);
1671}
1672
1673void Camera2Client::notifyShutter(int frameNumber, nsecs_t timestamp) {
1674 ALOGV("%s: Shutter notification for frame %d at time %lld", __FUNCTION__,
1675 frameNumber, timestamp);
1676}
1677
1678void Camera2Client::notifyAutoFocus(uint8_t newState, int triggerId) {
1679 ALOGV("%s: Autofocus state now %d, last trigger %d",
1680 __FUNCTION__, newState, triggerId);
1681}
1682
1683void Camera2Client::notifyAutoExposure(uint8_t newState, int triggerId) {
1684 ALOGV("%s: Autoexposure state now %d, last trigger %d",
1685 __FUNCTION__, newState, triggerId);
1686}
1687
1688void Camera2Client::notifyAutoWhitebalance(uint8_t newState, int triggerId) {
1689 ALOGV("%s: Auto-whitebalance state now %d, last trigger %d",
1690 __FUNCTION__, newState, triggerId);
1691}
1692
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001693void Camera2Client::onCaptureAvailable() {
1694 ATRACE_CALL();
1695 status_t res;
1696 sp<ICameraClient> currentClient;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001697 ALOGV("%s: Camera %d: Still capture available", __FUNCTION__, mCameraId);
1698
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001699 CpuConsumer::LockedBuffer imgBuffer;
1700 {
1701 Mutex::Autolock icl(mICameraLock);
1702
1703 // TODO: Signal errors here upstream
1704 if (mState != STILL_CAPTURE && mState != VIDEO_SNAPSHOT) {
1705 ALOGE("%s: Camera %d: Still image produced unexpectedly!",
1706 __FUNCTION__, mCameraId);
1707 return;
1708 }
1709
1710 res = mCaptureConsumer->lockNextBuffer(&imgBuffer);
1711 if (res != OK) {
1712 ALOGE("%s: Camera %d: Error receiving still image buffer: %s (%d)",
1713 __FUNCTION__, mCameraId, strerror(-res), res);
1714 return;
1715 }
1716
1717 if (imgBuffer.format != HAL_PIXEL_FORMAT_BLOB) {
1718 ALOGE("%s: Camera %d: Unexpected format for still image: "
1719 "%x, expected %x", __FUNCTION__, mCameraId,
1720 imgBuffer.format,
1721 HAL_PIXEL_FORMAT_BLOB);
1722 mCaptureConsumer->unlockBuffer(imgBuffer);
1723 return;
1724 }
1725
1726 // TODO: Optimize this to avoid memcopy
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001727 void* captureMemory = mCaptureHeap->mHeap->getBase();
1728 size_t size = mCaptureHeap->mHeap->getSize();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001729 memcpy(captureMemory, imgBuffer.data, size);
1730
1731 mCaptureConsumer->unlockBuffer(imgBuffer);
1732
1733 currentClient = mCameraClient;
1734 switch (mState) {
1735 case STILL_CAPTURE:
1736 mState = STOPPED;
1737 break;
1738 case VIDEO_SNAPSHOT:
1739 mState = RECORD;
1740 break;
1741 default:
1742 ALOGE("%s: Camera %d: Unexpected state %d", __FUNCTION__,
1743 mCameraId, mState);
1744 break;
1745 }
1746 }
1747 // Call outside mICameraLock to allow re-entrancy from notification
1748 if (currentClient != 0) {
1749 currentClient->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001750 mCaptureHeap->mBuffers[0], NULL);
1751 }
1752}
1753
1754void Camera2Client::onRecordingFrameAvailable() {
1755 ATRACE_CALL();
1756 status_t res;
1757 sp<ICameraClient> currentClient;
1758 size_t heapIdx = 0;
1759 nsecs_t timestamp;
1760 {
1761 Mutex::Autolock icl(mICameraLock);
1762 // TODO: Signal errors here upstream
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001763 bool discardData = false;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001764 if (mState != RECORD && mState != VIDEO_SNAPSHOT) {
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001765 ALOGV("%s: Camera %d: Discarding recording image buffers received after "
1766 "recording done",
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001767 __FUNCTION__, mCameraId);
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001768 discardData = true;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001769 }
1770
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001771 buffer_handle_t imgBuffer;
1772 res = mRecordingConsumer->getNextBuffer(&imgBuffer, &timestamp);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001773 if (res != OK) {
1774 ALOGE("%s: Camera %d: Error receiving recording buffer: %s (%d)",
1775 __FUNCTION__, mCameraId, strerror(-res), res);
1776 return;
1777 }
1778
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001779 if (discardData) {
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001780 mRecordingConsumer->freeBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001781 return;
1782 }
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001783
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001784 if (mRecordingHeap == 0) {
1785 const size_t bufferSize = 4 + sizeof(buffer_handle_t);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001786 ALOGV("%s: Camera %d: Creating recording heap with %d buffers of "
1787 "size %d bytes", __FUNCTION__, mCameraId,
James Dong983cf232012-08-01 16:39:55 -07001788 mRecordingHeapCount, bufferSize);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001789 if (mRecordingHeap != 0) {
1790 ALOGV("%s: Camera %d: Previous heap has size %d "
1791 "(new will be %d) bytes", __FUNCTION__, mCameraId,
1792 mRecordingHeap->mHeap->getSize(),
James Dong983cf232012-08-01 16:39:55 -07001793 bufferSize * mRecordingHeapCount);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001794 }
1795 // Need to allocate memory for heap
1796 mRecordingHeap.clear();
1797
James Dong983cf232012-08-01 16:39:55 -07001798 mRecordingHeap = new Camera2Heap(bufferSize, mRecordingHeapCount,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001799 "Camera2Client::RecordingHeap");
1800 if (mRecordingHeap->mHeap->getSize() == 0) {
1801 ALOGE("%s: Camera %d: Unable to allocate memory for recording",
1802 __FUNCTION__, mCameraId);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001803 mRecordingConsumer->freeBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001804 return;
1805 }
1806 mRecordingHeapHead = 0;
James Dong983cf232012-08-01 16:39:55 -07001807 mRecordingHeapFree = mRecordingHeapCount;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001808 }
1809
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001810 if ( mRecordingHeapFree == 0) {
1811 ALOGE("%s: Camera %d: No free recording buffers, dropping frame",
1812 __FUNCTION__, mCameraId);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001813 mRecordingConsumer->freeBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001814 return;
1815 }
1816 heapIdx = mRecordingHeapHead;
James Dong983cf232012-08-01 16:39:55 -07001817 mRecordingHeapHead = (mRecordingHeapHead + 1) % mRecordingHeapCount;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001818 mRecordingHeapFree--;
1819
1820 ALOGV("%s: Camera %d: Timestamp %lld",
1821 __FUNCTION__, mCameraId, timestamp);
1822
1823 ssize_t offset;
1824 size_t size;
1825 sp<IMemoryHeap> heap =
1826 mRecordingHeap->mBuffers[heapIdx]->getMemory(&offset,
1827 &size);
1828
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001829 uint8_t *data = (uint8_t*)heap->getBase() + offset;
1830 uint32_t type = kMetadataBufferTypeGrallocSource;
1831 memcpy(data, &type, 4);
1832 memcpy(data + 4, &imgBuffer, sizeof(buffer_handle_t));
1833 ALOGV("%s: Camera %d: Sending out buffer_handle_t %p",
Eino-Ville Talvala803cbf62012-07-25 15:23:36 -07001834 __FUNCTION__, mCameraId, imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001835 currentClient = mCameraClient;
1836 }
1837 // Call outside mICameraLock to allow re-entrancy from notification
1838 if (currentClient != 0) {
1839 currentClient->dataCallbackTimestamp(timestamp,
1840 CAMERA_MSG_VIDEO_FRAME,
1841 mRecordingHeap->mBuffers[heapIdx]);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001842 }
1843}
1844
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001845camera_metadata_entry_t Camera2Client::staticInfo(uint32_t tag,
1846 size_t minCount, size_t maxCount) {
1847 status_t res;
1848 camera_metadata_entry_t entry;
1849 res = find_camera_metadata_entry(mDevice->info(),
1850 tag,
1851 &entry);
1852 if (CC_UNLIKELY( res != OK )) {
1853 const char* tagSection = get_camera_metadata_section_name(tag);
1854 if (tagSection == NULL) tagSection = "<unknown>";
1855 const char* tagName = get_camera_metadata_tag_name(tag);
1856 if (tagName == NULL) tagName = "<unknown>";
1857
1858 ALOGE("Error finding static metadata entry '%s.%s' (%x): %s (%d)",
1859 tagSection, tagName, tag, strerror(-res), res);
1860 entry.count = 0;
1861 entry.data.u8 = NULL;
1862 } else if (CC_UNLIKELY(
1863 (minCount != 0 && entry.count < minCount) ||
1864 (maxCount != 0 && entry.count > maxCount) ) ) {
1865 const char* tagSection = get_camera_metadata_section_name(tag);
1866 if (tagSection == NULL) tagSection = "<unknown>";
1867 const char* tagName = get_camera_metadata_tag_name(tag);
1868 if (tagName == NULL) tagName = "<unknown>";
1869 ALOGE("Malformed static metadata entry '%s.%s' (%x):"
1870 "Expected between %d and %d values, but got %d values",
1871 tagSection, tagName, tag, minCount, maxCount, entry.count);
1872 entry.count = 0;
1873 entry.data.u8 = NULL;
1874 }
1875
1876 return entry;
1877}
1878
1879/** Utility methods */
1880
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001881
1882status_t Camera2Client::buildDefaultParameters() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001883 ATRACE_CALL();
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001884 LockedParameters::Key k(mParameters);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001885
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001886 status_t res;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001887 CameraParameters params;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001888
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001889 camera_metadata_entry_t availableProcessedSizes =
1890 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES, 2);
1891 if (!availableProcessedSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001892
1893 // TODO: Pick more intelligently
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001894 k.mParameters.previewWidth = availableProcessedSizes.data.i32[0];
1895 k.mParameters.previewHeight = availableProcessedSizes.data.i32[1];
1896 k.mParameters.videoWidth = k.mParameters.previewWidth;
1897 k.mParameters.videoHeight = k.mParameters.previewHeight;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001898
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001899 params.setPreviewSize(k.mParameters.previewWidth, k.mParameters.previewHeight);
1900 params.setVideoSize(k.mParameters.videoWidth, k.mParameters.videoHeight);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001901 params.set(CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO,
1902 String8::format("%dx%d",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001903 k.mParameters.previewWidth, k.mParameters.previewHeight));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001904 {
1905 String8 supportedPreviewSizes;
1906 for (size_t i=0; i < availableProcessedSizes.count; i += 2) {
1907 if (i != 0) supportedPreviewSizes += ",";
1908 supportedPreviewSizes += String8::format("%dx%d",
1909 availableProcessedSizes.data.i32[i],
1910 availableProcessedSizes.data.i32[i+1]);
1911 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001912 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001913 supportedPreviewSizes);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001914 params.set(CameraParameters::KEY_SUPPORTED_VIDEO_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001915 supportedPreviewSizes);
1916 }
1917
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001918 camera_metadata_entry_t availableFpsRanges =
1919 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
1920 if (!availableFpsRanges.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001921
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001922 k.mParameters.previewFpsRange[0] = availableFpsRanges.data.i32[0];
1923 k.mParameters.previewFpsRange[1] = availableFpsRanges.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001924
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001925 params.set(CameraParameters::KEY_PREVIEW_FPS_RANGE,
1926 String8::format("%d,%d",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001927 k.mParameters.previewFpsRange[0],
1928 k.mParameters.previewFpsRange[1]));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001929
1930 {
1931 String8 supportedPreviewFpsRange;
1932 for (size_t i=0; i < availableFpsRanges.count; i += 2) {
1933 if (i != 0) supportedPreviewFpsRange += ",";
1934 supportedPreviewFpsRange += String8::format("(%d,%d)",
1935 availableFpsRanges.data.i32[i],
1936 availableFpsRanges.data.i32[i+1]);
1937 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001938 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001939 supportedPreviewFpsRange);
1940 }
1941
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001942 k.mParameters.previewFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001943 params.set(CameraParameters::KEY_PREVIEW_FORMAT,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001944 formatEnumToString(k.mParameters.previewFormat)); // NV21
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001945
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001946 k.mParameters.previewTransform = degToTransform(0,
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001947 mCameraFacing == CAMERA_FACING_FRONT);
1948
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001949 camera_metadata_entry_t availableFormats =
1950 staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
1951
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001952 {
1953 String8 supportedPreviewFormats;
1954 bool addComma = false;
1955 for (size_t i=0; i < availableFormats.count; i++) {
1956 if (addComma) supportedPreviewFormats += ",";
1957 addComma = true;
1958 switch (availableFormats.data.i32[i]) {
1959 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001960 supportedPreviewFormats +=
1961 CameraParameters::PIXEL_FORMAT_YUV422SP;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001962 break;
1963 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001964 supportedPreviewFormats +=
1965 CameraParameters::PIXEL_FORMAT_YUV420SP;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001966 break;
1967 case HAL_PIXEL_FORMAT_YCbCr_422_I:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001968 supportedPreviewFormats +=
1969 CameraParameters::PIXEL_FORMAT_YUV422I;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001970 break;
1971 case HAL_PIXEL_FORMAT_YV12:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001972 supportedPreviewFormats +=
1973 CameraParameters::PIXEL_FORMAT_YUV420P;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001974 break;
1975 case HAL_PIXEL_FORMAT_RGB_565:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001976 supportedPreviewFormats +=
1977 CameraParameters::PIXEL_FORMAT_RGB565;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001978 break;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001979 case HAL_PIXEL_FORMAT_RGBA_8888:
1980 supportedPreviewFormats +=
1981 CameraParameters::PIXEL_FORMAT_RGBA8888;
1982 break;
1983 // Not advertizing JPEG, RAW_SENSOR, etc, for preview formats
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001984 case HAL_PIXEL_FORMAT_RAW_SENSOR:
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001985 case HAL_PIXEL_FORMAT_BLOB:
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001986 addComma = false;
1987 break;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001988
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001989 default:
1990 ALOGW("%s: Camera %d: Unknown preview format: %x",
1991 __FUNCTION__, mCameraId, availableFormats.data.i32[i]);
1992 addComma = false;
1993 break;
1994 }
1995 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001996 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001997 supportedPreviewFormats);
1998 }
1999
2000 // PREVIEW_FRAME_RATE / SUPPORTED_PREVIEW_FRAME_RATES are deprecated, but
2001 // still have to do something sane for them
2002
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002003 params.set(CameraParameters::KEY_PREVIEW_FRAME_RATE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002004 k.mParameters.previewFpsRange[0]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002005
2006 {
2007 String8 supportedPreviewFrameRates;
2008 for (size_t i=0; i < availableFpsRanges.count; i += 2) {
2009 if (i != 0) supportedPreviewFrameRates += ",";
2010 supportedPreviewFrameRates += String8::format("%d",
2011 availableFpsRanges.data.i32[i]);
2012 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002013 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002014 supportedPreviewFrameRates);
2015 }
2016
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002017 camera_metadata_entry_t availableJpegSizes =
2018 staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES, 2);
2019 if (!availableJpegSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002020
2021 // TODO: Pick maximum
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002022 k.mParameters.pictureWidth = availableJpegSizes.data.i32[0];
2023 k.mParameters.pictureHeight = availableJpegSizes.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002024
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002025 params.setPictureSize(k.mParameters.pictureWidth,
2026 k.mParameters.pictureHeight);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002027
2028 {
2029 String8 supportedPictureSizes;
2030 for (size_t i=0; i < availableJpegSizes.count; i += 2) {
2031 if (i != 0) supportedPictureSizes += ",";
2032 supportedPictureSizes += String8::format("%dx%d",
2033 availableJpegSizes.data.i32[i],
2034 availableJpegSizes.data.i32[i+1]);
2035 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002036 params.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002037 supportedPictureSizes);
2038 }
2039
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002040 params.setPictureFormat(CameraParameters::PIXEL_FORMAT_JPEG);
2041 params.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS,
2042 CameraParameters::PIXEL_FORMAT_JPEG);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002043
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002044 camera_metadata_entry_t availableJpegThumbnailSizes =
2045 staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES, 2);
2046 if (!availableJpegThumbnailSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002047
2048 // TODO: Pick default thumbnail size sensibly
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002049 k.mParameters.jpegThumbSize[0] = availableJpegThumbnailSizes.data.i32[0];
2050 k.mParameters.jpegThumbSize[1] = availableJpegThumbnailSizes.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002051
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002052 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002053 k.mParameters.jpegThumbSize[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002054 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002055 k.mParameters.jpegThumbSize[1]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002056
2057 {
2058 String8 supportedJpegThumbSizes;
2059 for (size_t i=0; i < availableJpegThumbnailSizes.count; i += 2) {
2060 if (i != 0) supportedJpegThumbSizes += ",";
2061 supportedJpegThumbSizes += String8::format("%dx%d",
2062 availableJpegThumbnailSizes.data.i32[i],
2063 availableJpegThumbnailSizes.data.i32[i+1]);
2064 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002065 params.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002066 supportedJpegThumbSizes);
2067 }
2068
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002069 k.mParameters.jpegThumbQuality = 90;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002070 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002071 k.mParameters.jpegThumbQuality);
2072 k.mParameters.jpegQuality = 90;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002073 params.set(CameraParameters::KEY_JPEG_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002074 k.mParameters.jpegQuality);
2075 k.mParameters.jpegRotation = 0;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002076 params.set(CameraParameters::KEY_ROTATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002077 k.mParameters.jpegRotation);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002078
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002079 k.mParameters.gpsEnabled = false;
2080 k.mParameters.gpsProcessingMethod = "unknown";
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002081 // GPS fields in CameraParameters are not set by implementation
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002082
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002083 k.mParameters.wbMode = ANDROID_CONTROL_AWB_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002084 params.set(CameraParameters::KEY_WHITE_BALANCE,
2085 CameraParameters::WHITE_BALANCE_AUTO);
2086
2087 camera_metadata_entry_t availableWhiteBalanceModes =
2088 staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002089 {
2090 String8 supportedWhiteBalance;
2091 bool addComma = false;
2092 for (size_t i=0; i < availableWhiteBalanceModes.count; i++) {
2093 if (addComma) supportedWhiteBalance += ",";
2094 addComma = true;
2095 switch (availableWhiteBalanceModes.data.u8[i]) {
2096 case ANDROID_CONTROL_AWB_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002097 supportedWhiteBalance +=
2098 CameraParameters::WHITE_BALANCE_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002099 break;
2100 case ANDROID_CONTROL_AWB_INCANDESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002101 supportedWhiteBalance +=
2102 CameraParameters::WHITE_BALANCE_INCANDESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002103 break;
2104 case ANDROID_CONTROL_AWB_FLUORESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002105 supportedWhiteBalance +=
2106 CameraParameters::WHITE_BALANCE_FLUORESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002107 break;
2108 case ANDROID_CONTROL_AWB_WARM_FLUORESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002109 supportedWhiteBalance +=
2110 CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002111 break;
2112 case ANDROID_CONTROL_AWB_DAYLIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002113 supportedWhiteBalance +=
2114 CameraParameters::WHITE_BALANCE_DAYLIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002115 break;
2116 case ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002117 supportedWhiteBalance +=
2118 CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002119 break;
2120 case ANDROID_CONTROL_AWB_TWILIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002121 supportedWhiteBalance +=
2122 CameraParameters::WHITE_BALANCE_TWILIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002123 break;
2124 case ANDROID_CONTROL_AWB_SHADE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002125 supportedWhiteBalance +=
2126 CameraParameters::WHITE_BALANCE_SHADE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002127 break;
2128 // Skipping values not mappable to v1 API
2129 case ANDROID_CONTROL_AWB_OFF:
2130 addComma = false;
2131 break;
2132 default:
2133 ALOGW("%s: Camera %d: Unknown white balance value: %d",
2134 __FUNCTION__, mCameraId,
2135 availableWhiteBalanceModes.data.u8[i]);
2136 addComma = false;
2137 break;
2138 }
2139 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002140 params.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002141 supportedWhiteBalance);
2142 }
2143
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002144 k.mParameters.effectMode = ANDROID_CONTROL_EFFECT_OFF;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002145 params.set(CameraParameters::KEY_EFFECT,
2146 CameraParameters::EFFECT_NONE);
2147
2148 camera_metadata_entry_t availableEffects =
2149 staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
2150 if (!availableEffects.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002151 {
2152 String8 supportedEffects;
2153 bool addComma = false;
2154 for (size_t i=0; i < availableEffects.count; i++) {
2155 if (addComma) supportedEffects += ",";
2156 addComma = true;
2157 switch (availableEffects.data.u8[i]) {
2158 case ANDROID_CONTROL_EFFECT_OFF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002159 supportedEffects +=
2160 CameraParameters::EFFECT_NONE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002161 break;
2162 case ANDROID_CONTROL_EFFECT_MONO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002163 supportedEffects +=
2164 CameraParameters::EFFECT_MONO;
2165 break;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002166 case ANDROID_CONTROL_EFFECT_NEGATIVE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002167 supportedEffects +=
2168 CameraParameters::EFFECT_NEGATIVE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002169 break;
2170 case ANDROID_CONTROL_EFFECT_SOLARIZE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002171 supportedEffects +=
2172 CameraParameters::EFFECT_SOLARIZE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002173 break;
2174 case ANDROID_CONTROL_EFFECT_SEPIA:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002175 supportedEffects +=
2176 CameraParameters::EFFECT_SEPIA;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002177 break;
2178 case ANDROID_CONTROL_EFFECT_POSTERIZE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002179 supportedEffects +=
2180 CameraParameters::EFFECT_POSTERIZE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002181 break;
2182 case ANDROID_CONTROL_EFFECT_WHITEBOARD:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002183 supportedEffects +=
2184 CameraParameters::EFFECT_WHITEBOARD;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002185 break;
2186 case ANDROID_CONTROL_EFFECT_BLACKBOARD:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002187 supportedEffects +=
2188 CameraParameters::EFFECT_BLACKBOARD;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002189 break;
2190 case ANDROID_CONTROL_EFFECT_AQUA:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002191 supportedEffects +=
2192 CameraParameters::EFFECT_AQUA;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002193 break;
2194 default:
2195 ALOGW("%s: Camera %d: Unknown effect value: %d",
2196 __FUNCTION__, mCameraId, availableEffects.data.u8[i]);
2197 addComma = false;
2198 break;
2199 }
2200 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002201 params.set(CameraParameters::KEY_SUPPORTED_EFFECTS, supportedEffects);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002202 }
2203
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002204 k.mParameters.antibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002205 params.set(CameraParameters::KEY_ANTIBANDING,
2206 CameraParameters::ANTIBANDING_AUTO);
2207
2208 camera_metadata_entry_t availableAntibandingModes =
2209 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
2210 if (!availableAntibandingModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002211 {
2212 String8 supportedAntibanding;
2213 bool addComma = false;
2214 for (size_t i=0; i < availableAntibandingModes.count; i++) {
2215 if (addComma) supportedAntibanding += ",";
2216 addComma = true;
2217 switch (availableAntibandingModes.data.u8[i]) {
2218 case ANDROID_CONTROL_AE_ANTIBANDING_OFF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002219 supportedAntibanding +=
2220 CameraParameters::ANTIBANDING_OFF;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002221 break;
2222 case ANDROID_CONTROL_AE_ANTIBANDING_50HZ:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002223 supportedAntibanding +=
2224 CameraParameters::ANTIBANDING_50HZ;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002225 break;
2226 case ANDROID_CONTROL_AE_ANTIBANDING_60HZ:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002227 supportedAntibanding +=
2228 CameraParameters::ANTIBANDING_60HZ;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002229 break;
2230 case ANDROID_CONTROL_AE_ANTIBANDING_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002231 supportedAntibanding +=
2232 CameraParameters::ANTIBANDING_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002233 break;
2234 default:
2235 ALOGW("%s: Camera %d: Unknown antibanding value: %d",
2236 __FUNCTION__, mCameraId,
2237 availableAntibandingModes.data.u8[i]);
2238 addComma = false;
2239 break;
2240 }
2241 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002242 params.set(CameraParameters::KEY_SUPPORTED_ANTIBANDING,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002243 supportedAntibanding);
2244 }
2245
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002246 k.mParameters.sceneMode = ANDROID_CONTROL_OFF;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002247 params.set(CameraParameters::KEY_SCENE_MODE,
2248 CameraParameters::SCENE_MODE_AUTO);
2249
2250 camera_metadata_entry_t availableSceneModes =
2251 staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
2252 if (!availableSceneModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002253 {
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002254 String8 supportedSceneModes(CameraParameters::SCENE_MODE_AUTO);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002255 bool addComma = true;
2256 bool noSceneModes = false;
2257 for (size_t i=0; i < availableSceneModes.count; i++) {
2258 if (addComma) supportedSceneModes += ",";
2259 addComma = true;
2260 switch (availableSceneModes.data.u8[i]) {
2261 case ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED:
2262 noSceneModes = true;
2263 break;
2264 case ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY:
2265 // Not in old API
2266 addComma = false;
2267 break;
2268 case ANDROID_CONTROL_SCENE_MODE_ACTION:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002269 supportedSceneModes +=
2270 CameraParameters::SCENE_MODE_ACTION;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002271 break;
2272 case ANDROID_CONTROL_SCENE_MODE_PORTRAIT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002273 supportedSceneModes +=
2274 CameraParameters::SCENE_MODE_PORTRAIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002275 break;
2276 case ANDROID_CONTROL_SCENE_MODE_LANDSCAPE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002277 supportedSceneModes +=
2278 CameraParameters::SCENE_MODE_LANDSCAPE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002279 break;
2280 case ANDROID_CONTROL_SCENE_MODE_NIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002281 supportedSceneModes +=
2282 CameraParameters::SCENE_MODE_NIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002283 break;
2284 case ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002285 supportedSceneModes +=
2286 CameraParameters::SCENE_MODE_NIGHT_PORTRAIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002287 break;
2288 case ANDROID_CONTROL_SCENE_MODE_THEATRE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002289 supportedSceneModes +=
2290 CameraParameters::SCENE_MODE_THEATRE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002291 break;
2292 case ANDROID_CONTROL_SCENE_MODE_BEACH:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002293 supportedSceneModes +=
2294 CameraParameters::SCENE_MODE_BEACH;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002295 break;
2296 case ANDROID_CONTROL_SCENE_MODE_SNOW:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002297 supportedSceneModes +=
2298 CameraParameters::SCENE_MODE_SNOW;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002299 break;
2300 case ANDROID_CONTROL_SCENE_MODE_SUNSET:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002301 supportedSceneModes +=
2302 CameraParameters::SCENE_MODE_SUNSET;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002303 break;
2304 case ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002305 supportedSceneModes +=
2306 CameraParameters::SCENE_MODE_STEADYPHOTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002307 break;
2308 case ANDROID_CONTROL_SCENE_MODE_FIREWORKS:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002309 supportedSceneModes +=
2310 CameraParameters::SCENE_MODE_FIREWORKS;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002311 break;
2312 case ANDROID_CONTROL_SCENE_MODE_SPORTS:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002313 supportedSceneModes +=
2314 CameraParameters::SCENE_MODE_SPORTS;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002315 break;
2316 case ANDROID_CONTROL_SCENE_MODE_PARTY:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002317 supportedSceneModes +=
2318 CameraParameters::SCENE_MODE_PARTY;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002319 break;
2320 case ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002321 supportedSceneModes +=
2322 CameraParameters::SCENE_MODE_CANDLELIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002323 break;
2324 case ANDROID_CONTROL_SCENE_MODE_BARCODE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002325 supportedSceneModes +=
2326 CameraParameters::SCENE_MODE_BARCODE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002327 break;
2328 default:
2329 ALOGW("%s: Camera %d: Unknown scene mode value: %d",
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002330 __FUNCTION__, mCameraId,
2331 availableSceneModes.data.u8[i]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002332 addComma = false;
2333 break;
2334 }
2335 }
2336 if (!noSceneModes) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002337 params.set(CameraParameters::KEY_SUPPORTED_SCENE_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002338 supportedSceneModes);
2339 }
2340 }
2341
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002342 camera_metadata_entry_t flashAvailable =
2343 staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
2344 if (!flashAvailable.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002345
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002346 camera_metadata_entry_t availableAeModes =
2347 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
2348 if (!availableAeModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002349
2350 if (flashAvailable.data.u8[0]) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002351 k.mParameters.flashMode = Parameters::FLASH_MODE_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002352 params.set(CameraParameters::KEY_FLASH_MODE,
2353 CameraParameters::FLASH_MODE_AUTO);
2354
2355 String8 supportedFlashModes(CameraParameters::FLASH_MODE_OFF);
2356 supportedFlashModes = supportedFlashModes +
2357 "," + CameraParameters::FLASH_MODE_AUTO +
2358 "," + CameraParameters::FLASH_MODE_ON +
2359 "," + CameraParameters::FLASH_MODE_TORCH;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002360 for (size_t i=0; i < availableAeModes.count; i++) {
2361 if (availableAeModes.data.u8[i] ==
2362 ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002363 supportedFlashModes = supportedFlashModes + "," +
2364 CameraParameters::FLASH_MODE_RED_EYE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002365 break;
2366 }
2367 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002368 params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002369 supportedFlashModes);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002370 } else {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002371 k.mParameters.flashMode = Parameters::FLASH_MODE_OFF;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002372 params.set(CameraParameters::KEY_FLASH_MODE,
2373 CameraParameters::FLASH_MODE_OFF);
2374 params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
2375 CameraParameters::FLASH_MODE_OFF);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002376 }
2377
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002378 camera_metadata_entry_t minFocusDistance =
2379 staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE, 1, 1);
2380 if (!minFocusDistance.count) return NO_INIT;
2381
2382 camera_metadata_entry_t availableAfModes =
2383 staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
2384 if (!availableAfModes.count) return NO_INIT;
2385
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002386 if (minFocusDistance.data.f[0] == 0) {
2387 // Fixed-focus lens
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002388 k.mParameters.focusMode = Parameters::FOCUS_MODE_FIXED;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002389 params.set(CameraParameters::KEY_FOCUS_MODE,
2390 CameraParameters::FOCUS_MODE_FIXED);
2391 params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
2392 CameraParameters::FOCUS_MODE_FIXED);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002393 } else {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002394 k.mParameters.focusMode = Parameters::FOCUS_MODE_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002395 params.set(CameraParameters::KEY_FOCUS_MODE,
2396 CameraParameters::FOCUS_MODE_AUTO);
2397 String8 supportedFocusModes(CameraParameters::FOCUS_MODE_FIXED);
2398 supportedFocusModes = supportedFocusModes + "," +
2399 CameraParameters::FOCUS_MODE_INFINITY;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002400 bool addComma = true;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002401
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002402 for (size_t i=0; i < availableAfModes.count; i++) {
2403 if (addComma) supportedFocusModes += ",";
2404 addComma = true;
2405 switch (availableAfModes.data.u8[i]) {
2406 case ANDROID_CONTROL_AF_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002407 supportedFocusModes +=
2408 CameraParameters::FOCUS_MODE_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002409 break;
2410 case ANDROID_CONTROL_AF_MACRO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002411 supportedFocusModes +=
2412 CameraParameters::FOCUS_MODE_MACRO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002413 break;
2414 case ANDROID_CONTROL_AF_CONTINUOUS_VIDEO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002415 supportedFocusModes +=
2416 CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002417 break;
2418 case ANDROID_CONTROL_AF_CONTINUOUS_PICTURE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002419 supportedFocusModes +=
2420 CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002421 break;
2422 case ANDROID_CONTROL_AF_EDOF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002423 supportedFocusModes +=
2424 CameraParameters::FOCUS_MODE_EDOF;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002425 break;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002426 // Not supported in old API
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002427 case ANDROID_CONTROL_AF_OFF:
2428 addComma = false;
2429 break;
2430 default:
2431 ALOGW("%s: Camera %d: Unknown AF mode value: %d",
2432 __FUNCTION__, mCameraId, availableAfModes.data.u8[i]);
2433 addComma = false;
2434 break;
2435 }
2436 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002437 params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002438 supportedFocusModes);
2439 }
2440
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002441 camera_metadata_entry_t max3aRegions =
2442 staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1);
2443 if (!max3aRegions.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002444
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002445 params.set(CameraParameters::KEY_MAX_NUM_FOCUS_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002446 max3aRegions.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002447 params.set(CameraParameters::KEY_FOCUS_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002448 "(0,0,0,0,0)");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002449 k.mParameters.focusingAreas.clear();
2450 k.mParameters.focusingAreas.add(Parameters::Area(0,0,0,0,0));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002451
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002452 camera_metadata_entry_t availableFocalLengths =
2453 staticInfo(ANDROID_LENS_AVAILABLE_FOCAL_LENGTHS);
2454 if (!availableFocalLengths.count) return NO_INIT;
2455
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002456 float minFocalLength = availableFocalLengths.data.f[0];
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002457 params.setFloat(CameraParameters::KEY_FOCAL_LENGTH, minFocalLength);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002458
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002459 camera_metadata_entry_t sensorSize =
2460 staticInfo(ANDROID_SENSOR_PHYSICAL_SIZE, 2, 2);
2461 if (!sensorSize.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002462
2463 // The fields of view here assume infinity focus, maximum wide angle
2464 float horizFov = 180 / M_PI *
2465 2 * atanf(sensorSize.data.f[0] / (2 * minFocalLength));
2466 float vertFov = 180 / M_PI *
2467 2 * atanf(sensorSize.data.f[1] / (2 * minFocalLength));
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002468 params.setFloat(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, horizFov);
2469 params.setFloat(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, vertFov);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002470
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002471 k.mParameters.exposureCompensation = 0;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002472 params.set(CameraParameters::KEY_EXPOSURE_COMPENSATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002473 k.mParameters.exposureCompensation);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002474
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002475 camera_metadata_entry_t exposureCompensationRange =
2476 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE, 2, 2);
2477 if (!exposureCompensationRange.count) return NO_INIT;
2478
2479 params.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002480 exposureCompensationRange.data.i32[1]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002481 params.set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002482 exposureCompensationRange.data.i32[0]);
2483
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002484 camera_metadata_entry_t exposureCompensationStep =
2485 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_STEP, 1, 1);
2486 if (!exposureCompensationStep.count) return NO_INIT;
2487
2488 params.setFloat(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP,
Eino-Ville Talvalad6f8e082012-08-02 16:00:35 -07002489 (float)exposureCompensationStep.data.r[0].numerator /
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002490 exposureCompensationStep.data.r[0].denominator);
2491
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002492 k.mParameters.autoExposureLock = false;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002493 params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK,
2494 CameraParameters::FALSE);
2495 params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED,
2496 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002497
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002498 k.mParameters.autoWhiteBalanceLock = false;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002499 params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK,
2500 CameraParameters::FALSE);
2501 params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED,
2502 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002503
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002504 k.mParameters.meteringAreas.add(Parameters::Area(0, 0, 0, 0, 0));
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002505 params.set(CameraParameters::KEY_MAX_NUM_METERING_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002506 max3aRegions.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002507 params.set(CameraParameters::KEY_METERING_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002508 "(0,0,0,0,0)");
2509
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002510 k.mParameters.zoom = 0;
2511 params.set(CameraParameters::KEY_ZOOM, k.mParameters.zoom);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002512 params.set(CameraParameters::KEY_MAX_ZOOM, NUM_ZOOM_STEPS - 1);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002513
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002514 camera_metadata_entry_t maxDigitalZoom =
2515 staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM, 1, 1);
2516 if (!maxDigitalZoom.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002517
2518 {
2519 String8 zoomRatios;
2520 float zoom = 1.f;
2521 float zoomIncrement = (maxDigitalZoom.data.f[0] - zoom) /
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002522 (NUM_ZOOM_STEPS-1);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002523 bool addComma = false;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002524 for (size_t i=0; i < NUM_ZOOM_STEPS; i++) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002525 if (addComma) zoomRatios += ",";
2526 addComma = true;
2527 zoomRatios += String8::format("%d", static_cast<int>(zoom * 100));
2528 zoom += zoomIncrement;
2529 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002530 params.set(CameraParameters::KEY_ZOOM_RATIOS, zoomRatios);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002531 }
2532
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002533 params.set(CameraParameters::KEY_ZOOM_SUPPORTED,
2534 CameraParameters::TRUE);
2535 params.set(CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED,
2536 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002537
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002538 params.set(CameraParameters::KEY_FOCUS_DISTANCES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002539 "Infinity,Infinity,Infinity");
2540
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002541 camera_metadata_entry_t maxFacesDetected =
2542 staticInfo(ANDROID_STATS_MAX_FACE_COUNT, 1, 1);
2543 params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002544 maxFacesDetected.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002545 params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002546 0);
2547
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002548 params.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT,
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002549 CameraParameters::PIXEL_FORMAT_ANDROID_OPAQUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002550
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002551 params.set(CameraParameters::KEY_RECORDING_HINT,
2552 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002553
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002554 params.set(CameraParameters::KEY_VIDEO_SNAPSHOT_SUPPORTED,
2555 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002556
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002557 params.set(CameraParameters::KEY_VIDEO_STABILIZATION,
2558 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002559
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002560 camera_metadata_entry_t availableVideoStabilizationModes =
2561 staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
2562 if (!availableVideoStabilizationModes.count) return NO_INIT;
2563
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002564 if (availableVideoStabilizationModes.count > 1) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002565 params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
2566 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002567 } else {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002568 params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
2569 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002570 }
2571
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07002572 // Set up initial state for non-Camera.Parameters state variables
2573
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002574 k.mParameters.storeMetadataInBuffers = true;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07002575 k.mParameters.playShutterSound = true;
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002576
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002577 k.mParameters.paramsFlattened = params.flatten();
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002578
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002579 return OK;
2580}
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07002581
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002582status_t Camera2Client::updatePreviewStream(const Parameters &params) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002583 ATRACE_CALL();
2584 status_t res;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002585
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002586 if (mPreviewStreamId != NO_STREAM) {
2587 // Check if stream parameters have to change
2588 uint32_t currentWidth, currentHeight;
2589 res = mDevice->getStreamInfo(mPreviewStreamId,
2590 &currentWidth, &currentHeight, 0);
2591 if (res != OK) {
2592 ALOGE("%s: Camera %d: Error querying preview stream info: "
2593 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2594 return res;
2595 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002596 if (currentWidth != (uint32_t)params.previewWidth ||
2597 currentHeight != (uint32_t)params.previewHeight) {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -07002598 ALOGV("%s: Camera %d: Preview size switch: %d x %d -> %d x %d",
2599 __FUNCTION__, mCameraId, currentWidth, currentHeight,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002600 params.previewWidth, params.previewHeight);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002601 res = mDevice->waitUntilDrained();
2602 if (res != OK) {
2603 ALOGE("%s: Camera %d: Error waiting for preview to drain: "
2604 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2605 return res;
2606 }
2607 res = mDevice->deleteStream(mPreviewStreamId);
2608 if (res != OK) {
2609 ALOGE("%s: Camera %d: Unable to delete old output stream "
2610 "for preview: %s (%d)", __FUNCTION__, mCameraId,
2611 strerror(-res), res);
2612 return res;
2613 }
2614 mPreviewStreamId = NO_STREAM;
2615 }
2616 }
2617
2618 if (mPreviewStreamId == NO_STREAM) {
2619 res = mDevice->createStream(mPreviewWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002620 params.previewWidth, params.previewHeight,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002621 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0,
2622 &mPreviewStreamId);
2623 if (res != OK) {
2624 ALOGE("%s: Camera %d: Unable to create preview stream: %s (%d)",
2625 __FUNCTION__, mCameraId, strerror(-res), res);
2626 return res;
2627 }
2628 }
2629
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07002630 res = mDevice->setStreamTransform(mPreviewStreamId,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002631 params.previewTransform);
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07002632 if (res != OK) {
2633 ALOGE("%s: Camera %d: Unable to set preview stream transform: "
2634 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2635 return res;
2636 }
2637
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002638 return OK;
2639}
2640
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002641status_t Camera2Client::updatePreviewRequest(const Parameters &params) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07002642 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002643 status_t res;
2644 if (mPreviewRequest == NULL) {
2645 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
2646 &mPreviewRequest);
2647 if (res != OK) {
2648 ALOGE("%s: Camera %d: Unable to create default preview request: "
2649 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2650 return res;
2651 }
2652 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002653
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002654 res = updateRequestCommon(mPreviewRequest, params);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002655 if (res != OK) {
2656 ALOGE("%s: Camera %d: Unable to update common entries of preview "
2657 "request: %s (%d)", __FUNCTION__, mCameraId,
2658 strerror(-res), res);
2659 return res;
2660 }
2661
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002662 return OK;
2663}
2664
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002665status_t Camera2Client::updateCaptureStream(const Parameters &params) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002666 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002667 status_t res;
2668 // Find out buffer size for JPEG
2669 camera_metadata_entry_t maxJpegSize =
2670 staticInfo(ANDROID_JPEG_MAX_SIZE);
2671 if (maxJpegSize.count == 0) {
2672 ALOGE("%s: Camera %d: Can't find ANDROID_JPEG_MAX_SIZE!",
2673 __FUNCTION__, mCameraId);
2674 return INVALID_OPERATION;
2675 }
2676
2677 if (mCaptureConsumer == 0) {
2678 // Create CPU buffer queue endpoint
2679 mCaptureConsumer = new CpuConsumer(1);
2680 mCaptureConsumer->setFrameAvailableListener(new CaptureWaiter(this));
2681 mCaptureConsumer->setName(String8("Camera2Client::CaptureConsumer"));
2682 mCaptureWindow = new SurfaceTextureClient(
2683 mCaptureConsumer->getProducerInterface());
2684 // Create memory for API consumption
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002685 mCaptureHeap = new Camera2Heap(maxJpegSize.data.i32[0], 1,
2686 "Camera2Client::CaptureHeap");
2687 if (mCaptureHeap->mHeap->getSize() == 0) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002688 ALOGE("%s: Camera %d: Unable to allocate memory for capture",
2689 __FUNCTION__, mCameraId);
2690 return NO_MEMORY;
2691 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002692 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002693
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002694 if (mCaptureStreamId != NO_STREAM) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002695 // Check if stream parameters have to change
2696 uint32_t currentWidth, currentHeight;
2697 res = mDevice->getStreamInfo(mCaptureStreamId,
2698 &currentWidth, &currentHeight, 0);
2699 if (res != OK) {
2700 ALOGE("%s: Camera %d: Error querying capture output stream info: "
2701 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2702 return res;
2703 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002704 if (currentWidth != (uint32_t)params.pictureWidth ||
2705 currentHeight != (uint32_t)params.pictureHeight) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002706 res = mDevice->deleteStream(mCaptureStreamId);
2707 if (res != OK) {
2708 ALOGE("%s: Camera %d: Unable to delete old output stream "
2709 "for capture: %s (%d)", __FUNCTION__, mCameraId,
2710 strerror(-res), res);
2711 return res;
2712 }
2713 mCaptureStreamId = NO_STREAM;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002714 }
2715 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002716
2717 if (mCaptureStreamId == NO_STREAM) {
2718 // Create stream for HAL production
2719 res = mDevice->createStream(mCaptureWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002720 params.pictureWidth, params.pictureHeight,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002721 HAL_PIXEL_FORMAT_BLOB, maxJpegSize.data.i32[0],
2722 &mCaptureStreamId);
2723 if (res != OK) {
2724 ALOGE("%s: Camera %d: Can't create output stream for capture: "
2725 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2726 return res;
2727 }
2728
2729 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002730 return OK;
2731}
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002732
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002733status_t Camera2Client::updateCaptureRequest(const Parameters &params) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002734 ATRACE_CALL();
2735 status_t res;
2736 if (mCaptureRequest == NULL) {
2737 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_STILL_CAPTURE,
2738 &mCaptureRequest);
2739 if (res != OK) {
2740 ALOGE("%s: Camera %d: Unable to create default still image request:"
2741 " %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2742 return res;
2743 }
2744 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002745
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002746 res = updateRequestCommon(mCaptureRequest, params);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002747 if (res != OK) {
2748 ALOGE("%s: Camera %d: Unable to update common entries of capture "
2749 "request: %s (%d)", __FUNCTION__, mCameraId,
2750 strerror(-res), res);
2751 return res;
2752 }
2753
2754 res = updateEntry(mCaptureRequest,
2755 ANDROID_JPEG_THUMBNAIL_SIZE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002756 params.jpegThumbSize, 2);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002757 if (res != OK) return res;
2758 res = updateEntry(mCaptureRequest,
2759 ANDROID_JPEG_THUMBNAIL_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002760 &params.jpegThumbQuality, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002761 if (res != OK) return res;
2762 res = updateEntry(mCaptureRequest,
2763 ANDROID_JPEG_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002764 &params.jpegQuality, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002765 if (res != OK) return res;
2766 res = updateEntry(mCaptureRequest,
2767 ANDROID_JPEG_ORIENTATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002768 &params.jpegRotation, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002769 if (res != OK) return res;
2770
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002771 if (params.gpsEnabled) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002772 res = updateEntry(mCaptureRequest,
2773 ANDROID_JPEG_GPS_COORDINATES,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002774 params.gpsCoordinates, 3);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002775 if (res != OK) return res;
2776 res = updateEntry(mCaptureRequest,
2777 ANDROID_JPEG_GPS_TIMESTAMP,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002778 &params.gpsTimestamp, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002779 if (res != OK) return res;
2780 res = updateEntry(mCaptureRequest,
2781 ANDROID_JPEG_GPS_PROCESSING_METHOD,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002782 params.gpsProcessingMethod.string(),
2783 params.gpsProcessingMethod.size());
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002784 if (res != OK) return res;
2785 } else {
2786 res = deleteEntry(mCaptureRequest,
2787 ANDROID_JPEG_GPS_COORDINATES);
2788 if (res != OK) return res;
2789 res = deleteEntry(mCaptureRequest,
2790 ANDROID_JPEG_GPS_TIMESTAMP);
2791 if (res != OK) return res;
2792 res = deleteEntry(mCaptureRequest,
2793 ANDROID_JPEG_GPS_PROCESSING_METHOD);
2794 if (res != OK) return res;
2795 }
2796
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002797 return OK;
2798}
2799
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002800status_t Camera2Client::updateRecordingRequest(const Parameters &params) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002801 ATRACE_CALL();
2802 status_t res;
2803 if (mRecordingRequest == NULL) {
2804 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_VIDEO_RECORD,
2805 &mRecordingRequest);
2806 if (res != OK) {
2807 ALOGE("%s: Camera %d: Unable to create default recording request:"
2808 " %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2809 return res;
2810 }
2811 }
2812
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002813 res = updateRequestCommon(mRecordingRequest, params);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002814 if (res != OK) {
2815 ALOGE("%s: Camera %d: Unable to update common entries of recording "
2816 "request: %s (%d)", __FUNCTION__, mCameraId,
2817 strerror(-res), res);
2818 return res;
2819 }
2820
2821 return OK;
2822}
2823
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002824status_t Camera2Client::updateRecordingStream(const Parameters &params) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002825 status_t res;
2826
2827 if (mRecordingConsumer == 0) {
2828 // Create CPU buffer queue endpoint
James Dong983cf232012-08-01 16:39:55 -07002829 mRecordingConsumer = new MediaConsumer(mRecordingHeapCount);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002830 mRecordingConsumer->setFrameAvailableListener(new RecordingWaiter(this));
2831 mRecordingConsumer->setName(String8("Camera2Client::RecordingConsumer"));
2832 mRecordingWindow = new SurfaceTextureClient(
2833 mRecordingConsumer->getProducerInterface());
2834 // Allocate memory later, since we don't know buffer size until receipt
2835 }
2836
2837 if (mRecordingStreamId != NO_STREAM) {
2838 // Check if stream parameters have to change
2839 uint32_t currentWidth, currentHeight;
2840 res = mDevice->getStreamInfo(mRecordingStreamId,
2841 &currentWidth, &currentHeight, 0);
2842 if (res != OK) {
2843 ALOGE("%s: Camera %d: Error querying recording output stream info: "
2844 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2845 return res;
2846 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002847 if (currentWidth != (uint32_t)params.videoWidth ||
2848 currentHeight != (uint32_t)params.videoHeight) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002849 // TODO: Should wait to be sure previous recording has finished
2850 res = mDevice->deleteStream(mRecordingStreamId);
2851 if (res != OK) {
2852 ALOGE("%s: Camera %d: Unable to delete old output stream "
2853 "for recording: %s (%d)", __FUNCTION__, mCameraId,
2854 strerror(-res), res);
2855 return res;
2856 }
2857 mRecordingStreamId = NO_STREAM;
2858 }
2859 }
2860
2861 if (mRecordingStreamId == NO_STREAM) {
2862 res = mDevice->createStream(mRecordingWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002863 params.videoWidth, params.videoHeight,
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002864 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0, &mRecordingStreamId);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002865 if (res != OK) {
2866 ALOGE("%s: Camera %d: Can't create output stream for recording: "
2867 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2868 return res;
2869 }
2870 }
2871
2872 return OK;
2873}
2874
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002875status_t Camera2Client::updateRequestCommon(camera_metadata_t *request,
2876 const Parameters &params) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002877 ATRACE_CALL();
2878 status_t res;
2879 res = updateEntry(request,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002880 ANDROID_CONTROL_AE_TARGET_FPS_RANGE, params.previewFpsRange, 2);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002881 if (res != OK) return res;
2882
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002883 uint8_t wbMode = params.autoWhiteBalanceLock ?
2884 ANDROID_CONTROL_AWB_LOCKED : params.wbMode;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002885 res = updateEntry(request,
2886 ANDROID_CONTROL_AWB_MODE, &wbMode, 1);
2887 if (res != OK) return res;
2888 res = updateEntry(request,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002889 ANDROID_CONTROL_EFFECT_MODE, &params.effectMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002890 if (res != OK) return res;
2891 res = updateEntry(request,
2892 ANDROID_CONTROL_AE_ANTIBANDING_MODE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002893 &params.antibandingMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002894 if (res != OK) return res;
2895
2896 uint8_t controlMode =
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002897 (params.sceneMode == ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED) ?
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002898 ANDROID_CONTROL_AUTO : ANDROID_CONTROL_USE_SCENE_MODE;
2899 res = updateEntry(request,
2900 ANDROID_CONTROL_MODE, &controlMode, 1);
2901 if (res != OK) return res;
2902 if (controlMode == ANDROID_CONTROL_USE_SCENE_MODE) {
2903 res = updateEntry(request,
2904 ANDROID_CONTROL_SCENE_MODE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002905 &params.sceneMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002906 if (res != OK) return res;
2907 }
2908
2909 uint8_t flashMode = ANDROID_FLASH_OFF;
2910 uint8_t aeMode;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002911 switch (params.flashMode) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002912 case Parameters::FLASH_MODE_OFF:
2913 aeMode = ANDROID_CONTROL_AE_ON; break;
2914 case Parameters::FLASH_MODE_AUTO:
2915 aeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH; break;
2916 case Parameters::FLASH_MODE_ON:
2917 aeMode = ANDROID_CONTROL_AE_ON_ALWAYS_FLASH; break;
2918 case Parameters::FLASH_MODE_TORCH:
2919 aeMode = ANDROID_CONTROL_AE_ON;
2920 flashMode = ANDROID_FLASH_TORCH;
2921 break;
2922 case Parameters::FLASH_MODE_RED_EYE:
2923 aeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE; break;
2924 default:
2925 ALOGE("%s: Camera %d: Unknown flash mode %d", __FUNCTION__,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002926 mCameraId, params.flashMode);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002927 return BAD_VALUE;
2928 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002929 if (params.autoExposureLock) aeMode = ANDROID_CONTROL_AE_LOCKED;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002930
2931 res = updateEntry(request,
2932 ANDROID_FLASH_MODE, &flashMode, 1);
2933 if (res != OK) return res;
2934 res = updateEntry(request,
2935 ANDROID_CONTROL_AE_MODE, &aeMode, 1);
2936 if (res != OK) return res;
2937
2938 float focusDistance = 0; // infinity focus in diopters
2939 uint8_t focusMode;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002940 switch (params.focusMode) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002941 case Parameters::FOCUS_MODE_AUTO:
2942 case Parameters::FOCUS_MODE_MACRO:
2943 case Parameters::FOCUS_MODE_CONTINUOUS_VIDEO:
2944 case Parameters::FOCUS_MODE_CONTINUOUS_PICTURE:
2945 case Parameters::FOCUS_MODE_EDOF:
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002946 focusMode = params.focusMode;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002947 break;
2948 case Parameters::FOCUS_MODE_INFINITY:
2949 case Parameters::FOCUS_MODE_FIXED:
2950 focusMode = ANDROID_CONTROL_AF_OFF;
2951 break;
2952 default:
2953 ALOGE("%s: Camera %d: Unknown focus mode %d", __FUNCTION__,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002954 mCameraId, params.focusMode);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002955 return BAD_VALUE;
2956 }
2957 res = updateEntry(request,
2958 ANDROID_LENS_FOCUS_DISTANCE, &focusDistance, 1);
2959 if (res != OK) return res;
2960 res = updateEntry(request,
2961 ANDROID_CONTROL_AF_MODE, &focusMode, 1);
2962 if (res != OK) return res;
2963
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002964 size_t focusingAreasSize = params.focusingAreas.size() * 5;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002965 int32_t *focusingAreas = new int32_t[focusingAreasSize];
2966 for (size_t i = 0; i < focusingAreasSize; i += 5) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002967 focusingAreas[i + 0] = params.focusingAreas[i].left;
2968 focusingAreas[i + 1] = params.focusingAreas[i].top;
2969 focusingAreas[i + 2] = params.focusingAreas[i].right;
2970 focusingAreas[i + 3] = params.focusingAreas[i].bottom;
2971 focusingAreas[i + 4] = params.focusingAreas[i].weight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002972 }
2973 res = updateEntry(request,
2974 ANDROID_CONTROL_AF_REGIONS, focusingAreas,focusingAreasSize);
2975 if (res != OK) return res;
2976 delete[] focusingAreas;
2977
2978 res = updateEntry(request,
2979 ANDROID_CONTROL_AE_EXP_COMPENSATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002980 &params.exposureCompensation, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002981 if (res != OK) return res;
2982
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002983 size_t meteringAreasSize = params.meteringAreas.size() * 5;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002984 int32_t *meteringAreas = new int32_t[meteringAreasSize];
2985 for (size_t i = 0; i < meteringAreasSize; i += 5) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002986 meteringAreas[i + 0] = params.meteringAreas[i].left;
2987 meteringAreas[i + 1] = params.meteringAreas[i].top;
2988 meteringAreas[i + 2] = params.meteringAreas[i].right;
2989 meteringAreas[i + 3] = params.meteringAreas[i].bottom;
2990 meteringAreas[i + 4] = params.meteringAreas[i].weight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002991 }
2992 res = updateEntry(request,
2993 ANDROID_CONTROL_AE_REGIONS, meteringAreas, meteringAreasSize);
2994 if (res != OK) return res;
2995
2996 res = updateEntry(request,
2997 ANDROID_CONTROL_AWB_REGIONS, meteringAreas, meteringAreasSize);
2998 if (res != OK) return res;
2999 delete[] meteringAreas;
3000
3001 // Need to convert zoom index into a crop rectangle. The rectangle is
3002 // chosen to maximize its area on the sensor
3003
3004 camera_metadata_entry_t maxDigitalZoom =
3005 staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM);
3006 float zoomIncrement = (maxDigitalZoom.data.f[0] - 1) /
3007 (NUM_ZOOM_STEPS-1);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003008 float zoomRatio = 1 + zoomIncrement * params.zoom;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003009
3010 camera_metadata_entry_t activePixelArraySize =
3011 staticInfo(ANDROID_SENSOR_ACTIVE_ARRAY_SIZE, 2, 2);
3012 int32_t arrayWidth = activePixelArraySize.data.i32[0];
3013 int32_t arrayHeight = activePixelArraySize.data.i32[1];
3014 float zoomLeft, zoomTop, zoomWidth, zoomHeight;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003015 if (params.previewWidth >= params.previewHeight) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003016 zoomWidth = arrayWidth / zoomRatio;
3017 zoomHeight = zoomWidth *
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003018 params.previewHeight / params.previewWidth;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003019 } else {
3020 zoomHeight = arrayHeight / zoomRatio;
3021 zoomWidth = zoomHeight *
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003022 params.previewWidth / params.previewHeight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003023 }
3024 zoomLeft = (arrayWidth - zoomWidth) / 2;
3025 zoomTop = (arrayHeight - zoomHeight) / 2;
3026
3027 int32_t cropRegion[3] = { zoomLeft, zoomTop, zoomWidth };
3028 res = updateEntry(request,
3029 ANDROID_SCALER_CROP_REGION, cropRegion, 3);
3030 if (res != OK) return res;
3031
3032 // TODO: Decide how to map recordingHint, or whether just to ignore it
3033
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003034 uint8_t vstabMode = params.videoStabilization ?
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003035 ANDROID_CONTROL_VIDEO_STABILIZATION_ON :
3036 ANDROID_CONTROL_VIDEO_STABILIZATION_OFF;
3037 res = updateEntry(request,
3038 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
3039 &vstabMode, 1);
3040 if (res != OK) return res;
3041
3042 return OK;
3043}
3044
3045status_t Camera2Client::updateEntry(camera_metadata_t *buffer,
3046 uint32_t tag, const void *data, size_t data_count) {
3047 camera_metadata_entry_t entry;
3048 status_t res;
3049 res = find_camera_metadata_entry(buffer, tag, &entry);
3050 if (res == NAME_NOT_FOUND) {
3051 res = add_camera_metadata_entry(buffer,
3052 tag, data, data_count);
3053 } else if (res == OK) {
3054 res = update_camera_metadata_entry(buffer,
3055 entry.index, data, data_count, NULL);
3056 }
3057
3058 if (res != OK) {
3059 ALOGE("%s: Unable to update metadata entry %s.%s (%x): %s (%d)",
3060 __FUNCTION__, get_camera_metadata_section_name(tag),
3061 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
3062 }
3063 return res;
3064}
3065
3066status_t Camera2Client::deleteEntry(camera_metadata_t *buffer, uint32_t tag) {
3067 camera_metadata_entry_t entry;
3068 status_t res;
3069 res = find_camera_metadata_entry(buffer, tag, &entry);
3070 if (res == NAME_NOT_FOUND) {
3071 return OK;
3072 } else if (res != OK) {
3073 ALOGE("%s: Error looking for entry %s.%s (%x): %s %d",
3074 __FUNCTION__,
3075 get_camera_metadata_section_name(tag),
3076 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
3077 return res;
3078 }
3079 res = delete_camera_metadata_entry(buffer, entry.index);
3080 if (res != OK) {
3081 ALOGE("%s: Error deleting entry %s.%s (%x): %s %d",
3082 __FUNCTION__,
3083 get_camera_metadata_section_name(tag),
3084 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
3085 }
3086 return res;
3087}
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003088
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07003089int Camera2Client::formatStringToEnum(const char *format) {
3090 return
3091 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422SP) ?
3092 HAL_PIXEL_FORMAT_YCbCr_422_SP : // NV16
3093 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420SP) ?
3094 HAL_PIXEL_FORMAT_YCrCb_420_SP : // NV21
3095 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422I) ?
3096 HAL_PIXEL_FORMAT_YCbCr_422_I : // YUY2
3097 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420P) ?
3098 HAL_PIXEL_FORMAT_YV12 : // YV12
3099 !strcmp(format, CameraParameters::PIXEL_FORMAT_RGB565) ?
3100 HAL_PIXEL_FORMAT_RGB_565 : // RGB565
3101 !strcmp(format, CameraParameters::PIXEL_FORMAT_RGBA8888) ?
3102 HAL_PIXEL_FORMAT_RGBA_8888 : // RGB8888
3103 !strcmp(format, CameraParameters::PIXEL_FORMAT_BAYER_RGGB) ?
3104 HAL_PIXEL_FORMAT_RAW_SENSOR : // Raw sensor data
3105 -1;
3106}
3107
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003108const char* Camera2Client::formatEnumToString(int format) {
3109 const char *fmt;
3110 switch(format) {
3111 case HAL_PIXEL_FORMAT_YCbCr_422_SP: // NV16
3112 fmt = CameraParameters::PIXEL_FORMAT_YUV422SP;
3113 break;
3114 case HAL_PIXEL_FORMAT_YCrCb_420_SP: // NV21
3115 fmt = CameraParameters::PIXEL_FORMAT_YUV420SP;
3116 break;
3117 case HAL_PIXEL_FORMAT_YCbCr_422_I: // YUY2
3118 fmt = CameraParameters::PIXEL_FORMAT_YUV422I;
3119 break;
3120 case HAL_PIXEL_FORMAT_YV12: // YV12
3121 fmt = CameraParameters::PIXEL_FORMAT_YUV420P;
3122 break;
3123 case HAL_PIXEL_FORMAT_RGB_565: // RGB565
3124 fmt = CameraParameters::PIXEL_FORMAT_RGB565;
3125 break;
3126 case HAL_PIXEL_FORMAT_RGBA_8888: // RGBA8888
3127 fmt = CameraParameters::PIXEL_FORMAT_RGBA8888;
3128 break;
3129 case HAL_PIXEL_FORMAT_RAW_SENSOR:
3130 ALOGW("Raw sensor preview format requested.");
3131 fmt = CameraParameters::PIXEL_FORMAT_BAYER_RGGB;
3132 break;
3133 default:
3134 ALOGE("%s: Unknown preview format: %x",
3135 __FUNCTION__, format);
3136 fmt = NULL;
3137 break;
3138 }
3139 return fmt;
3140}
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07003141
3142int Camera2Client::wbModeStringToEnum(const char *wbMode) {
3143 return
3144 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_AUTO) ?
3145 ANDROID_CONTROL_AWB_AUTO :
3146 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_INCANDESCENT) ?
3147 ANDROID_CONTROL_AWB_INCANDESCENT :
3148 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_FLUORESCENT) ?
3149 ANDROID_CONTROL_AWB_FLUORESCENT :
3150 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT) ?
3151 ANDROID_CONTROL_AWB_WARM_FLUORESCENT :
3152 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_DAYLIGHT) ?
3153 ANDROID_CONTROL_AWB_DAYLIGHT :
3154 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT) ?
3155 ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT :
3156 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_TWILIGHT) ?
3157 ANDROID_CONTROL_AWB_TWILIGHT :
3158 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_SHADE) ?
3159 ANDROID_CONTROL_AWB_SHADE :
3160 -1;
3161}
3162
3163int Camera2Client::effectModeStringToEnum(const char *effectMode) {
3164 return
3165 !strcmp(effectMode, CameraParameters::EFFECT_NONE) ?
3166 ANDROID_CONTROL_EFFECT_OFF :
3167 !strcmp(effectMode, CameraParameters::EFFECT_MONO) ?
3168 ANDROID_CONTROL_EFFECT_MONO :
3169 !strcmp(effectMode, CameraParameters::EFFECT_NEGATIVE) ?
3170 ANDROID_CONTROL_EFFECT_NEGATIVE :
3171 !strcmp(effectMode, CameraParameters::EFFECT_SOLARIZE) ?
3172 ANDROID_CONTROL_EFFECT_SOLARIZE :
3173 !strcmp(effectMode, CameraParameters::EFFECT_SEPIA) ?
3174 ANDROID_CONTROL_EFFECT_SEPIA :
3175 !strcmp(effectMode, CameraParameters::EFFECT_POSTERIZE) ?
3176 ANDROID_CONTROL_EFFECT_POSTERIZE :
3177 !strcmp(effectMode, CameraParameters::EFFECT_WHITEBOARD) ?
3178 ANDROID_CONTROL_EFFECT_WHITEBOARD :
3179 !strcmp(effectMode, CameraParameters::EFFECT_BLACKBOARD) ?
3180 ANDROID_CONTROL_EFFECT_BLACKBOARD :
3181 !strcmp(effectMode, CameraParameters::EFFECT_AQUA) ?
3182 ANDROID_CONTROL_EFFECT_AQUA :
3183 -1;
3184}
3185
3186int Camera2Client::abModeStringToEnum(const char *abMode) {
3187 return
3188 !strcmp(abMode, CameraParameters::ANTIBANDING_AUTO) ?
3189 ANDROID_CONTROL_AE_ANTIBANDING_AUTO :
3190 !strcmp(abMode, CameraParameters::ANTIBANDING_OFF) ?
3191 ANDROID_CONTROL_AE_ANTIBANDING_OFF :
3192 !strcmp(abMode, CameraParameters::ANTIBANDING_50HZ) ?
3193 ANDROID_CONTROL_AE_ANTIBANDING_50HZ :
3194 !strcmp(abMode, CameraParameters::ANTIBANDING_60HZ) ?
3195 ANDROID_CONTROL_AE_ANTIBANDING_60HZ :
3196 -1;
3197}
3198
3199int Camera2Client::sceneModeStringToEnum(const char *sceneMode) {
3200 return
3201 !strcmp(sceneMode, CameraParameters::SCENE_MODE_AUTO) ?
3202 ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED :
3203 !strcmp(sceneMode, CameraParameters::SCENE_MODE_ACTION) ?
3204 ANDROID_CONTROL_SCENE_MODE_ACTION :
3205 !strcmp(sceneMode, CameraParameters::SCENE_MODE_PORTRAIT) ?
3206 ANDROID_CONTROL_SCENE_MODE_PORTRAIT :
3207 !strcmp(sceneMode, CameraParameters::SCENE_MODE_LANDSCAPE) ?
3208 ANDROID_CONTROL_SCENE_MODE_LANDSCAPE :
3209 !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT) ?
3210 ANDROID_CONTROL_SCENE_MODE_NIGHT :
3211 !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT_PORTRAIT) ?
3212 ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT :
3213 !strcmp(sceneMode, CameraParameters::SCENE_MODE_THEATRE) ?
3214 ANDROID_CONTROL_SCENE_MODE_THEATRE :
3215 !strcmp(sceneMode, CameraParameters::SCENE_MODE_BEACH) ?
3216 ANDROID_CONTROL_SCENE_MODE_BEACH :
3217 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SNOW) ?
3218 ANDROID_CONTROL_SCENE_MODE_SNOW :
3219 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SUNSET) ?
3220 ANDROID_CONTROL_SCENE_MODE_SUNSET :
3221 !strcmp(sceneMode, CameraParameters::SCENE_MODE_STEADYPHOTO) ?
3222 ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO :
3223 !strcmp(sceneMode, CameraParameters::SCENE_MODE_FIREWORKS) ?
3224 ANDROID_CONTROL_SCENE_MODE_FIREWORKS :
3225 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SPORTS) ?
3226 ANDROID_CONTROL_SCENE_MODE_SPORTS :
3227 !strcmp(sceneMode, CameraParameters::SCENE_MODE_PARTY) ?
3228 ANDROID_CONTROL_SCENE_MODE_PARTY :
3229 !strcmp(sceneMode, CameraParameters::SCENE_MODE_CANDLELIGHT) ?
3230 ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT :
3231 !strcmp(sceneMode, CameraParameters::SCENE_MODE_BARCODE) ?
3232 ANDROID_CONTROL_SCENE_MODE_BARCODE:
3233 -1;
3234}
3235
3236Camera2Client::Parameters::flashMode_t Camera2Client::flashModeStringToEnum(
3237 const char *flashMode) {
3238 return
3239 !strcmp(flashMode, CameraParameters::FLASH_MODE_OFF) ?
3240 Parameters::FLASH_MODE_OFF :
3241 !strcmp(flashMode, CameraParameters::FLASH_MODE_AUTO) ?
3242 Parameters::FLASH_MODE_AUTO :
3243 !strcmp(flashMode, CameraParameters::FLASH_MODE_ON) ?
3244 Parameters::FLASH_MODE_ON :
3245 !strcmp(flashMode, CameraParameters::FLASH_MODE_RED_EYE) ?
3246 Parameters::FLASH_MODE_RED_EYE :
3247 !strcmp(flashMode, CameraParameters::FLASH_MODE_TORCH) ?
3248 Parameters::FLASH_MODE_TORCH :
3249 Parameters::FLASH_MODE_INVALID;
3250}
3251
3252Camera2Client::Parameters::focusMode_t Camera2Client::focusModeStringToEnum(
3253 const char *focusMode) {
3254 return
3255 !strcmp(focusMode, CameraParameters::FOCUS_MODE_AUTO) ?
3256 Parameters::FOCUS_MODE_AUTO :
3257 !strcmp(focusMode, CameraParameters::FOCUS_MODE_INFINITY) ?
3258 Parameters::FOCUS_MODE_INFINITY :
3259 !strcmp(focusMode, CameraParameters::FOCUS_MODE_MACRO) ?
3260 Parameters::FOCUS_MODE_MACRO :
3261 !strcmp(focusMode, CameraParameters::FOCUS_MODE_FIXED) ?
3262 Parameters::FOCUS_MODE_FIXED :
3263 !strcmp(focusMode, CameraParameters::FOCUS_MODE_EDOF) ?
3264 Parameters::FOCUS_MODE_EDOF :
3265 !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO) ?
3266 Parameters::FOCUS_MODE_CONTINUOUS_VIDEO :
3267 !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE) ?
3268 Parameters::FOCUS_MODE_CONTINUOUS_PICTURE :
3269 Parameters::FOCUS_MODE_INVALID;
3270}
3271
3272status_t Camera2Client::parseAreas(const char *areasCStr,
3273 Vector<Parameters::Area> *areas) {
3274 static const size_t NUM_FIELDS = 5;
3275 areas->clear();
3276 if (areasCStr == NULL) {
3277 // If no key exists, use default (0,0,0,0,0)
3278 areas->push();
3279 return OK;
3280 }
3281 String8 areasStr(areasCStr);
3282 ssize_t areaStart = areasStr.find("(", 0) + 1;
3283 while (areaStart != 0) {
3284 const char* area = areasStr.string() + areaStart;
3285 char *numEnd;
3286 int vals[NUM_FIELDS];
3287 for (size_t i = 0; i < NUM_FIELDS; i++) {
3288 errno = 0;
3289 vals[i] = strtol(area, &numEnd, 10);
3290 if (errno || numEnd == area) return BAD_VALUE;
3291 area = numEnd + 1;
3292 }
3293 areas->push(Parameters::Area(
3294 vals[0], vals[1], vals[2], vals[3], vals[4]) );
3295 areaStart = areasStr.find("(", areaStart) + 1;
3296 }
3297 return OK;
3298}
3299
3300status_t Camera2Client::validateAreas(const Vector<Parameters::Area> &areas,
3301 size_t maxRegions) {
3302 // Definition of valid area can be found in
3303 // include/camera/CameraParameters.h
3304 if (areas.size() == 0) return BAD_VALUE;
3305 if (areas.size() == 1) {
3306 if (areas[0].left == 0 &&
3307 areas[0].top == 0 &&
3308 areas[0].right == 0 &&
3309 areas[0].bottom == 0 &&
3310 areas[0].weight == 0) {
3311 // Single (0,0,0,0,0) entry is always valid (== driver decides)
3312 return OK;
3313 }
3314 }
3315 if (areas.size() > maxRegions) {
3316 ALOGE("%s: Too many areas requested: %d",
3317 __FUNCTION__, areas.size());
3318 return BAD_VALUE;
3319 }
3320
3321 for (Vector<Parameters::Area>::const_iterator a = areas.begin();
3322 a != areas.end(); a++) {
3323 if (a->weight < 1 || a->weight > 1000) return BAD_VALUE;
3324 if (a->left < -1000 || a->left > 1000) return BAD_VALUE;
3325 if (a->top < -1000 || a->top > 1000) return BAD_VALUE;
3326 if (a->right < -1000 || a->right > 1000) return BAD_VALUE;
3327 if (a->bottom < -1000 || a->bottom > 1000) return BAD_VALUE;
3328 if (a->left >= a->right) return BAD_VALUE;
3329 if (a->top >= a->bottom) return BAD_VALUE;
3330 }
3331 return OK;
3332}
3333
3334bool Camera2Client::boolFromString(const char *boolStr) {
3335 return !boolStr ? false :
3336 !strcmp(boolStr, CameraParameters::TRUE) ? true :
3337 false;
3338}
3339
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07003340int Camera2Client::degToTransform(int degrees, bool mirror) {
3341 if (!mirror) {
3342 if (degrees == 0) return 0;
3343 else if (degrees == 90) return HAL_TRANSFORM_ROT_90;
3344 else if (degrees == 180) return HAL_TRANSFORM_ROT_180;
3345 else if (degrees == 270) return HAL_TRANSFORM_ROT_270;
3346 } else { // Do mirror (horizontal flip)
3347 if (degrees == 0) { // FLIP_H and ROT_0
3348 return HAL_TRANSFORM_FLIP_H;
3349 } else if (degrees == 90) { // FLIP_H and ROT_90
3350 return HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90;
3351 } else if (degrees == 180) { // FLIP_H and ROT_180
3352 return HAL_TRANSFORM_FLIP_V;
3353 } else if (degrees == 270) { // FLIP_H and ROT_270
3354 return HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90;
3355 }
3356 }
3357 ALOGE("%s: Bad input: %d", __FUNCTION__, degrees);
3358 return -1;
3359}
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07003360
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07003361} // namespace android