blob: dfcc8c00eaa9365a332951c2c0324a5ac6edd51b [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);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700795 if ( checkPid(__FUNCTION__) != OK) return false;
796
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700797 return (mState == RECORD || mState == VIDEO_SNAPSHOT);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700798}
799
800void Camera2Client::releaseRecordingFrame(const sp<IMemory>& mem) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700801 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700802 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700803 status_t res;
804 if ( checkPid(__FUNCTION__) != OK) return;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700805 // Make sure this is for the current heap
806 ssize_t offset;
807 size_t size;
808 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
809 if (heap->getHeapID() != mRecordingHeap->mHeap->getHeapID()) {
810 ALOGW("%s: Camera %d: Mismatched heap ID, ignoring release "
811 "(got %x, expected %x)", __FUNCTION__, mCameraId,
812 heap->getHeapID(), mRecordingHeap->mHeap->getHeapID());
813 return;
814 }
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700815 uint8_t *data = (uint8_t*)heap->getBase() + offset;
816 uint32_t type = *(uint32_t*)data;
817 if (type != kMetadataBufferTypeGrallocSource) {
818 ALOGE("%s: Camera %d: Recording frame type invalid (got %x, expected %x)",
819 __FUNCTION__, mCameraId, type, kMetadataBufferTypeGrallocSource);
820 return;
821 }
822 buffer_handle_t imgBuffer = *(buffer_handle_t*)(data + 4);
823 ALOGV("%s: Camera %d: Freeing buffer_handle_t %p", __FUNCTION__, mCameraId,
Eino-Ville Talvala803cbf62012-07-25 15:23:36 -0700824 imgBuffer);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700825 res = mRecordingConsumer->freeBuffer(imgBuffer);
826 if (res != OK) {
827 ALOGE("%s: Camera %d: Unable to free recording frame (buffer_handle_t: %p):"
828 "%s (%d)",
829 __FUNCTION__, mCameraId, imgBuffer, strerror(-res), res);
830 return;
831 }
832
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700833 mRecordingHeapFree++;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700834}
835
836status_t Camera2Client::autoFocus() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700837 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700838 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700839 status_t res;
840 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
841
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700842 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700843}
844
845status_t Camera2Client::cancelAutoFocus() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700846 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700847 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700848 status_t res;
849 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
850
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700851 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700852}
853
854status_t Camera2Client::takePicture(int msgType) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700855 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700856 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700857 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700858 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700859
860 switch (mState) {
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700861 case DISCONNECTED:
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700862 case STOPPED:
863 case WAITING_FOR_PREVIEW_WINDOW:
864 ALOGE("%s: Camera %d: Cannot take picture without preview enabled",
865 __FUNCTION__, mCameraId);
866 return INVALID_OPERATION;
867 case PREVIEW:
868 case RECORD:
869 // Good to go for takePicture
870 break;
871 case STILL_CAPTURE:
872 case VIDEO_SNAPSHOT:
873 ALOGE("%s: Camera %d: Already taking a picture",
874 __FUNCTION__, mCameraId);
875 return INVALID_OPERATION;
876 }
877
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700878 LockedParameters::Key k(mParameters);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700879
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700880 res = updateCaptureStream(k.mParameters);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700881 if (res != OK) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700882 ALOGE("%s: Camera %d: Can't set up still image stream: %s (%d)",
883 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700884 return res;
885 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700886
887 if (mCaptureRequest == NULL) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700888 res = updateCaptureRequest(k.mParameters);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700889 if (res != OK) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700890 ALOGE("%s: Camera %d: Can't create still image capture request: "
891 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700892 return res;
893 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700894 }
895
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700896 camera_metadata_entry_t outputStreams;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700897 if (mState == PREVIEW) {
898 uint8_t streamIds[2] = { mPreviewStreamId, mCaptureStreamId };
899 res = updateEntry(mCaptureRequest, ANDROID_REQUEST_OUTPUT_STREAMS,
900 &streamIds, 2);
901 } else if (mState == RECORD) {
902 uint8_t streamIds[3] = { mPreviewStreamId, mRecordingStreamId,
903 mCaptureStreamId };
904 res = updateEntry(mCaptureRequest, ANDROID_REQUEST_OUTPUT_STREAMS,
905 &streamIds, 3);
906 }
907
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700908 if (res != OK) {
909 ALOGE("%s: Camera %d: Unable to set up still image capture request: "
910 "%s (%d)",
911 __FUNCTION__, mCameraId, strerror(-res), res);
912 return res;
913 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700914 res = sort_camera_metadata(mCaptureRequest);
915 if (res != OK) {
916 ALOGE("%s: Camera %d: Unable to sort capture request: %s (%d)",
917 __FUNCTION__, mCameraId, strerror(-res), res);
918 return res;
919 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700920
921 camera_metadata_t *captureCopy = clone_camera_metadata(mCaptureRequest);
922 if (captureCopy == NULL) {
923 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device",
924 __FUNCTION__, mCameraId);
925 return NO_MEMORY;
926 }
927
928 if (mState == PREVIEW) {
929 res = mDevice->setStreamingRequest(NULL);
930 if (res != OK) {
931 ALOGE("%s: Camera %d: Unable to stop preview for still capture: "
932 "%s (%d)",
933 __FUNCTION__, mCameraId, strerror(-res), res);
934 return res;
935 }
936 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700937 // TODO: Capture should be atomic with setStreamingRequest here
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700938 res = mDevice->capture(captureCopy);
939 if (res != OK) {
940 ALOGE("%s: Camera %d: Unable to submit still image capture request: "
941 "%s (%d)",
942 __FUNCTION__, mCameraId, strerror(-res), res);
943 return res;
944 }
945
946 switch (mState) {
947 case PREVIEW:
948 mState = STILL_CAPTURE;
949 break;
950 case RECORD:
951 mState = VIDEO_SNAPSHOT;
952 break;
953 default:
954 ALOGE("%s: Camera %d: Unknown state for still capture!",
955 __FUNCTION__, mCameraId);
956 return INVALID_OPERATION;
957 }
958
959 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700960}
961
962status_t Camera2Client::setParameters(const String8& params) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700963 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700964 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700965 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700966 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700967 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
968
969 LockedParameters::Key k(mParameters);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700970
971 CameraParameters newParams(params);
972
973 // TODO: Currently ignoring any changes to supposedly read-only
974 // parameters such as supported preview sizes, etc. Should probably
975 // produce an error if they're changed.
976
977 /** Extract and verify new parameters */
978
979 size_t i;
980
981 // PREVIEW_SIZE
982 int previewWidth, previewHeight;
983 newParams.getPreviewSize(&previewWidth, &previewHeight);
984
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700985 if (previewWidth != k.mParameters.previewWidth ||
986 previewHeight != k.mParameters.previewHeight) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700987 if (mState >= PREVIEW) {
988 ALOGE("%s: Preview size cannot be updated when preview "
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700989 "is active! (Currently %d x %d, requested %d x %d",
990 __FUNCTION__,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700991 k.mParameters.previewWidth, k.mParameters.previewHeight,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700992 previewWidth, previewHeight);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700993 return BAD_VALUE;
994 }
995 camera_metadata_entry_t availablePreviewSizes =
996 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
997 for (i = 0; i < availablePreviewSizes.count; i += 2 ) {
998 if (availablePreviewSizes.data.i32[i] == previewWidth &&
999 availablePreviewSizes.data.i32[i+1] == previewHeight) break;
1000 }
1001 if (i == availablePreviewSizes.count) {
1002 ALOGE("%s: Requested preview size %d x %d is not supported",
1003 __FUNCTION__, previewWidth, previewHeight);
1004 return BAD_VALUE;
1005 }
1006 }
1007
1008 // PREVIEW_FPS_RANGE
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001009 int previewFpsRange[2];
1010 int previewFps = 0;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001011 bool fpsRangeChanged = false;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001012 newParams.getPreviewFpsRange(&previewFpsRange[0], &previewFpsRange[1]);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001013 if (previewFpsRange[0] != k.mParameters.previewFpsRange[0] ||
1014 previewFpsRange[1] != k.mParameters.previewFpsRange[1]) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001015 fpsRangeChanged = true;
1016 camera_metadata_entry_t availablePreviewFpsRanges =
1017 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
1018 for (i = 0; i < availablePreviewFpsRanges.count; i += 2) {
1019 if ((availablePreviewFpsRanges.data.i32[i] ==
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001020 previewFpsRange[0]) &&
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001021 (availablePreviewFpsRanges.data.i32[i+1] ==
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001022 previewFpsRange[1]) ) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001023 break;
1024 }
1025 }
1026 if (i == availablePreviewFpsRanges.count) {
1027 ALOGE("%s: Requested preview FPS range %d - %d is not supported",
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001028 __FUNCTION__, previewFpsRange[0], previewFpsRange[1]);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001029 return BAD_VALUE;
1030 }
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001031 previewFps = previewFpsRange[0];
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001032 }
1033
1034 // PREVIEW_FORMAT
1035 int previewFormat = formatStringToEnum(newParams.getPreviewFormat());
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001036 if (previewFormat != k.mParameters.previewFormat) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001037 if (mState >= PREVIEW) {
1038 ALOGE("%s: Preview format cannot be updated when preview "
1039 "is active!", __FUNCTION__);
1040 return BAD_VALUE;
1041 }
1042 camera_metadata_entry_t availableFormats =
1043 staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
1044 for (i = 0; i < availableFormats.count; i++) {
1045 if (availableFormats.data.i32[i] == previewFormat) break;
1046 }
1047 if (i == availableFormats.count) {
1048 ALOGE("%s: Requested preview format %s (0x%x) is not supported",
1049 __FUNCTION__, newParams.getPreviewFormat(), previewFormat);
1050 return BAD_VALUE;
1051 }
1052 }
1053
1054 // PREVIEW_FRAME_RATE
1055 // Deprecated, only use if the preview fps range is unchanged this time.
1056 // The single-value FPS is the same as the minimum of the range.
1057 if (!fpsRangeChanged) {
1058 previewFps = newParams.getPreviewFrameRate();
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001059 if (previewFps != k.mParameters.previewFps) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001060 camera_metadata_entry_t availableFrameRates =
1061 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
1062 for (i = 0; i < availableFrameRates.count; i+=2) {
1063 if (availableFrameRates.data.i32[i] == previewFps) break;
1064 }
1065 if (i == availableFrameRates.count) {
1066 ALOGE("%s: Requested preview frame rate %d is not supported",
1067 __FUNCTION__, previewFps);
1068 return BAD_VALUE;
1069 }
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001070 previewFpsRange[0] = availableFrameRates.data.i32[i];
1071 previewFpsRange[1] = availableFrameRates.data.i32[i+1];
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001072 }
1073 }
1074
1075 // PICTURE_SIZE
1076 int pictureWidth, pictureHeight;
1077 newParams.getPictureSize(&pictureWidth, &pictureHeight);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001078 if (pictureWidth == k.mParameters.pictureWidth ||
1079 pictureHeight == k.mParameters.pictureHeight) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001080 camera_metadata_entry_t availablePictureSizes =
1081 staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES);
1082 for (i = 0; i < availablePictureSizes.count; i+=2) {
1083 if (availablePictureSizes.data.i32[i] == pictureWidth &&
1084 availablePictureSizes.data.i32[i+1] == pictureHeight) break;
1085 }
1086 if (i == availablePictureSizes.count) {
1087 ALOGE("%s: Requested picture size %d x %d is not supported",
1088 __FUNCTION__, pictureWidth, pictureHeight);
1089 return BAD_VALUE;
1090 }
1091 }
1092
1093 // JPEG_THUMBNAIL_WIDTH/HEIGHT
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001094 int jpegThumbSize[2];
1095 jpegThumbSize[0] =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001096 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001097 jpegThumbSize[1] =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001098 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001099 if (jpegThumbSize[0] != k.mParameters.jpegThumbSize[0] ||
1100 jpegThumbSize[1] != k.mParameters.jpegThumbSize[1]) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001101 camera_metadata_entry_t availableJpegThumbSizes =
1102 staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES);
1103 for (i = 0; i < availableJpegThumbSizes.count; i+=2) {
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001104 if (availableJpegThumbSizes.data.i32[i] == jpegThumbSize[0] &&
1105 availableJpegThumbSizes.data.i32[i+1] == jpegThumbSize[1]) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001106 break;
1107 }
1108 }
1109 if (i == availableJpegThumbSizes.count) {
1110 ALOGE("%s: Requested JPEG thumbnail size %d x %d is not supported",
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001111 __FUNCTION__, jpegThumbSize[0], jpegThumbSize[1]);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001112 return BAD_VALUE;
1113 }
1114 }
1115
1116 // JPEG_THUMBNAIL_QUALITY
1117 int jpegThumbQuality =
1118 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
1119 if (jpegThumbQuality < 0 || jpegThumbQuality > 100) {
1120 ALOGE("%s: Requested JPEG thumbnail quality %d is not supported",
1121 __FUNCTION__, jpegThumbQuality);
1122 return BAD_VALUE;
1123 }
1124
1125 // JPEG_QUALITY
1126 int jpegQuality =
1127 newParams.getInt(CameraParameters::KEY_JPEG_QUALITY);
1128 if (jpegQuality < 0 || jpegQuality > 100) {
1129 ALOGE("%s: Requested JPEG quality %d is not supported",
1130 __FUNCTION__, jpegQuality);
1131 return BAD_VALUE;
1132 }
1133
1134 // ROTATION
1135 int jpegRotation =
1136 newParams.getInt(CameraParameters::KEY_ROTATION);
1137 if (jpegRotation != 0 &&
1138 jpegRotation != 90 &&
1139 jpegRotation != 180 &&
1140 jpegRotation != 270) {
1141 ALOGE("%s: Requested picture rotation angle %d is not supported",
1142 __FUNCTION__, jpegRotation);
1143 return BAD_VALUE;
1144 }
1145
1146 // GPS
1147 bool gpsEnabled = false;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001148 double gpsCoordinates[3] = {0,0,0};
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001149 int64_t gpsTimestamp = 0;
1150 String8 gpsProcessingMethod;
1151 const char *gpsLatStr =
1152 newParams.get(CameraParameters::KEY_GPS_LATITUDE);
1153 if (gpsLatStr != NULL) {
1154 const char *gpsLongStr =
1155 newParams.get(CameraParameters::KEY_GPS_LONGITUDE);
1156 const char *gpsAltitudeStr =
1157 newParams.get(CameraParameters::KEY_GPS_ALTITUDE);
1158 const char *gpsTimeStr =
1159 newParams.get(CameraParameters::KEY_GPS_TIMESTAMP);
1160 const char *gpsProcMethodStr =
1161 newParams.get(CameraParameters::KEY_GPS_PROCESSING_METHOD);
1162 if (gpsLongStr == NULL ||
1163 gpsAltitudeStr == NULL ||
1164 gpsTimeStr == NULL ||
1165 gpsProcMethodStr == NULL) {
1166 ALOGE("%s: Incomplete set of GPS parameters provided",
1167 __FUNCTION__);
1168 return BAD_VALUE;
1169 }
1170 char *endPtr;
1171 errno = 0;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001172 gpsCoordinates[0] = strtod(gpsLatStr, &endPtr);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001173 if (errno || endPtr == gpsLatStr) {
1174 ALOGE("%s: Malformed GPS latitude: %s", __FUNCTION__, gpsLatStr);
1175 return BAD_VALUE;
1176 }
1177 errno = 0;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001178 gpsCoordinates[1] = strtod(gpsLongStr, &endPtr);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001179 if (errno || endPtr == gpsLongStr) {
1180 ALOGE("%s: Malformed GPS longitude: %s", __FUNCTION__, gpsLongStr);
1181 return BAD_VALUE;
1182 }
1183 errno = 0;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001184 gpsCoordinates[2] = strtod(gpsAltitudeStr, &endPtr);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001185 if (errno || endPtr == gpsAltitudeStr) {
1186 ALOGE("%s: Malformed GPS altitude: %s", __FUNCTION__,
1187 gpsAltitudeStr);
1188 return BAD_VALUE;
1189 }
1190 errno = 0;
1191 gpsTimestamp = strtoll(gpsTimeStr, &endPtr, 10);
1192 if (errno || endPtr == gpsTimeStr) {
1193 ALOGE("%s: Malformed GPS timestamp: %s", __FUNCTION__, gpsTimeStr);
1194 return BAD_VALUE;
1195 }
1196 gpsProcessingMethod = gpsProcMethodStr;
1197
1198 gpsEnabled = true;
1199 }
1200
1201 // WHITE_BALANCE
1202 int wbMode = wbModeStringToEnum(
1203 newParams.get(CameraParameters::KEY_WHITE_BALANCE) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001204 if (wbMode != k.mParameters.wbMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001205 camera_metadata_entry_t availableWbModes =
1206 staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
1207 for (i = 0; i < availableWbModes.count; i++) {
1208 if (wbMode == availableWbModes.data.u8[i]) break;
1209 }
1210 if (i == availableWbModes.count) {
1211 ALOGE("%s: Requested white balance mode %s is not supported",
1212 __FUNCTION__,
1213 newParams.get(CameraParameters::KEY_WHITE_BALANCE));
1214 return BAD_VALUE;
1215 }
1216 }
1217
1218 // EFFECT
1219 int effectMode = effectModeStringToEnum(
1220 newParams.get(CameraParameters::KEY_EFFECT) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001221 if (effectMode != k.mParameters.effectMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001222 camera_metadata_entry_t availableEffectModes =
1223 staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
1224 for (i = 0; i < availableEffectModes.count; i++) {
1225 if (effectMode == availableEffectModes.data.u8[i]) break;
1226 }
1227 if (i == availableEffectModes.count) {
1228 ALOGE("%s: Requested effect mode \"%s\" is not supported",
1229 __FUNCTION__,
1230 newParams.get(CameraParameters::KEY_EFFECT) );
1231 return BAD_VALUE;
1232 }
1233 }
1234
1235 // ANTIBANDING
1236 int antibandingMode = abModeStringToEnum(
1237 newParams.get(CameraParameters::KEY_ANTIBANDING) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001238 if (antibandingMode != k.mParameters.antibandingMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001239 camera_metadata_entry_t availableAbModes =
1240 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
1241 for (i = 0; i < availableAbModes.count; i++) {
1242 if (antibandingMode == availableAbModes.data.u8[i]) break;
1243 }
1244 if (i == availableAbModes.count) {
1245 ALOGE("%s: Requested antibanding mode \"%s\" is not supported",
1246 __FUNCTION__,
1247 newParams.get(CameraParameters::KEY_ANTIBANDING));
1248 return BAD_VALUE;
1249 }
1250 }
1251
1252 // SCENE_MODE
1253 int sceneMode = sceneModeStringToEnum(
1254 newParams.get(CameraParameters::KEY_SCENE_MODE) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001255 if (sceneMode != k.mParameters.sceneMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001256 camera_metadata_entry_t availableSceneModes =
1257 staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
1258 for (i = 0; i < availableSceneModes.count; i++) {
1259 if (sceneMode == availableSceneModes.data.u8[i]) break;
1260 }
1261 if (i == availableSceneModes.count) {
1262 ALOGE("%s: Requested scene mode \"%s\" is not supported",
1263 __FUNCTION__,
1264 newParams.get(CameraParameters::KEY_SCENE_MODE));
1265 return BAD_VALUE;
1266 }
1267 }
1268
1269 // FLASH_MODE
1270 Parameters::flashMode_t flashMode = flashModeStringToEnum(
1271 newParams.get(CameraParameters::KEY_FLASH_MODE) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001272 if (flashMode != k.mParameters.flashMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001273 camera_metadata_entry_t flashAvailable =
1274 staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
1275 if (!flashAvailable.data.u8[0] &&
1276 flashMode != Parameters::FLASH_MODE_OFF) {
1277 ALOGE("%s: Requested flash mode \"%s\" is not supported: "
1278 "No flash on device", __FUNCTION__,
1279 newParams.get(CameraParameters::KEY_FLASH_MODE));
1280 return BAD_VALUE;
1281 } else if (flashMode == Parameters::FLASH_MODE_RED_EYE) {
1282 camera_metadata_entry_t availableAeModes =
1283 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
1284 for (i = 0; i < availableAeModes.count; i++) {
1285 if (flashMode == availableAeModes.data.u8[i]) break;
1286 }
1287 if (i == availableAeModes.count) {
1288 ALOGE("%s: Requested flash mode \"%s\" is not supported",
1289 __FUNCTION__,
1290 newParams.get(CameraParameters::KEY_FLASH_MODE));
1291 return BAD_VALUE;
1292 }
1293 } else if (flashMode == -1) {
1294 ALOGE("%s: Requested flash mode \"%s\" is unknown",
1295 __FUNCTION__,
1296 newParams.get(CameraParameters::KEY_FLASH_MODE));
1297 return BAD_VALUE;
1298 }
1299 }
1300
1301 // FOCUS_MODE
1302 Parameters::focusMode_t focusMode = focusModeStringToEnum(
1303 newParams.get(CameraParameters::KEY_FOCUS_MODE));
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001304 if (focusMode != k.mParameters.focusMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001305 if (focusMode != Parameters::FOCUS_MODE_FIXED) {
1306 camera_metadata_entry_t minFocusDistance =
1307 staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE);
1308 if (minFocusDistance.data.f[0] == 0) {
1309 ALOGE("%s: Requested focus mode \"%s\" is not available: "
1310 "fixed focus lens",
1311 __FUNCTION__,
1312 newParams.get(CameraParameters::KEY_FOCUS_MODE));
1313 return BAD_VALUE;
1314 } else if (focusMode != Parameters::FOCUS_MODE_INFINITY) {
1315 camera_metadata_entry_t availableFocusModes =
1316 staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
1317 for (i = 0; i < availableFocusModes.count; i++) {
1318 if (focusMode == availableFocusModes.data.u8[i]) break;
1319 }
1320 if (i == availableFocusModes.count) {
1321 ALOGE("%s: Requested focus mode \"%s\" is not supported",
1322 __FUNCTION__,
1323 newParams.get(CameraParameters::KEY_FOCUS_MODE));
1324 return BAD_VALUE;
1325 }
1326 }
1327 }
1328 }
1329
1330 // FOCUS_AREAS
1331 Vector<Parameters::Area> focusingAreas;
1332 res = parseAreas(newParams.get(CameraParameters::KEY_FOCUS_AREAS),
1333 &focusingAreas);
1334 size_t max3aRegions =
1335 (size_t)staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1).data.i32[0];
1336 if (res == OK) res = validateAreas(focusingAreas, max3aRegions);
1337 if (res != OK) {
1338 ALOGE("%s: Requested focus areas are malformed: %s",
1339 __FUNCTION__, newParams.get(CameraParameters::KEY_FOCUS_AREAS));
1340 return BAD_VALUE;
1341 }
1342
1343 // EXPOSURE_COMPENSATION
1344 int exposureCompensation =
1345 newParams.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION);
1346 camera_metadata_entry_t exposureCompensationRange =
1347 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE);
1348 if (exposureCompensation < exposureCompensationRange.data.i32[0] ||
1349 exposureCompensation > exposureCompensationRange.data.i32[1]) {
1350 ALOGE("%s: Requested exposure compensation index is out of bounds: %d",
1351 __FUNCTION__, exposureCompensation);
1352 return BAD_VALUE;
1353 }
1354
1355 // AUTO_EXPOSURE_LOCK (always supported)
1356 bool autoExposureLock = boolFromString(
1357 newParams.get(CameraParameters::KEY_AUTO_EXPOSURE_LOCK));
1358
1359 // AUTO_WHITEBALANCE_LOCK (always supported)
1360 bool autoWhiteBalanceLock = boolFromString(
1361 newParams.get(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK));
1362
1363 // METERING_AREAS
1364 Vector<Parameters::Area> meteringAreas;
1365 res = parseAreas(newParams.get(CameraParameters::KEY_METERING_AREAS),
1366 &meteringAreas);
1367 if (res == OK) res = validateAreas(focusingAreas, max3aRegions);
1368 if (res != OK) {
1369 ALOGE("%s: Requested metering areas are malformed: %s",
1370 __FUNCTION__,
1371 newParams.get(CameraParameters::KEY_METERING_AREAS));
1372 return BAD_VALUE;
1373 }
1374
1375 // ZOOM
1376 int zoom = newParams.getInt(CameraParameters::KEY_ZOOM);
1377 if (zoom < 0 || zoom > (int)NUM_ZOOM_STEPS) {
1378 ALOGE("%s: Requested zoom level %d is not supported",
1379 __FUNCTION__, zoom);
1380 return BAD_VALUE;
1381 }
1382
1383 // VIDEO_SIZE
1384 int videoWidth, videoHeight;
1385 newParams.getVideoSize(&videoWidth, &videoHeight);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001386 if (videoWidth != k.mParameters.videoWidth ||
1387 videoHeight != k.mParameters.videoHeight) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001388 if (mState == RECORD) {
1389 ALOGE("%s: Video size cannot be updated when recording is active!",
1390 __FUNCTION__);
1391 return BAD_VALUE;
1392 }
1393 camera_metadata_entry_t availableVideoSizes =
1394 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
1395 for (i = 0; i < availableVideoSizes.count; i += 2 ) {
1396 if (availableVideoSizes.data.i32[i] == videoWidth &&
1397 availableVideoSizes.data.i32[i+1] == videoHeight) break;
1398 }
1399 if (i == availableVideoSizes.count) {
1400 ALOGE("%s: Requested video size %d x %d is not supported",
1401 __FUNCTION__, videoWidth, videoHeight);
1402 return BAD_VALUE;
1403 }
1404 }
1405
1406 // RECORDING_HINT (always supported)
1407 bool recordingHint = boolFromString(
1408 newParams.get(CameraParameters::KEY_RECORDING_HINT) );
1409
1410 // VIDEO_STABILIZATION
1411 bool videoStabilization = boolFromString(
1412 newParams.get(CameraParameters::KEY_VIDEO_STABILIZATION) );
1413 camera_metadata_entry_t availableVideoStabilizationModes =
1414 staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
1415 if (videoStabilization && availableVideoStabilizationModes.count == 1) {
1416 ALOGE("%s: Video stabilization not supported", __FUNCTION__);
1417 }
1418
1419 /** Update internal parameters */
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001420
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001421 k.mParameters.previewWidth = previewWidth;
1422 k.mParameters.previewHeight = previewHeight;
1423 k.mParameters.previewFpsRange[0] = previewFpsRange[0];
1424 k.mParameters.previewFpsRange[1] = previewFpsRange[1];
1425 k.mParameters.previewFps = previewFps;
1426 k.mParameters.previewFormat = previewFormat;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001427
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001428 k.mParameters.pictureWidth = pictureWidth;
1429 k.mParameters.pictureHeight = pictureHeight;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001430
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001431 k.mParameters.jpegThumbSize[0] = jpegThumbSize[0];
1432 k.mParameters.jpegThumbSize[1] = jpegThumbSize[1];
1433 k.mParameters.jpegQuality = jpegQuality;
1434 k.mParameters.jpegThumbQuality = jpegThumbQuality;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001435
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001436 k.mParameters.gpsEnabled = gpsEnabled;
1437 k.mParameters.gpsCoordinates[0] = gpsCoordinates[0];
1438 k.mParameters.gpsCoordinates[1] = gpsCoordinates[1];
1439 k.mParameters.gpsCoordinates[2] = gpsCoordinates[2];
1440 k.mParameters.gpsTimestamp = gpsTimestamp;
1441 k.mParameters.gpsProcessingMethod = gpsProcessingMethod;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001442
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001443 k.mParameters.wbMode = wbMode;
1444 k.mParameters.effectMode = effectMode;
1445 k.mParameters.antibandingMode = antibandingMode;
1446 k.mParameters.sceneMode = sceneMode;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001447
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001448 k.mParameters.flashMode = flashMode;
1449 k.mParameters.focusMode = focusMode;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001450
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001451 k.mParameters.focusingAreas = focusingAreas;
1452 k.mParameters.exposureCompensation = exposureCompensation;
1453 k.mParameters.autoExposureLock = autoExposureLock;
1454 k.mParameters.autoWhiteBalanceLock = autoWhiteBalanceLock;
1455 k.mParameters.meteringAreas = meteringAreas;
1456 k.mParameters.zoom = zoom;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001457
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001458 k.mParameters.videoWidth = videoWidth;
1459 k.mParameters.videoHeight = videoHeight;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001460
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001461 k.mParameters.recordingHint = recordingHint;
1462 k.mParameters.videoStabilization = videoStabilization;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001463
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001464 res = updatePreviewRequest(k.mParameters);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001465 if (res != OK) {
1466 ALOGE("%s: Camera %d: Unable to update preview request: %s (%d)",
1467 __FUNCTION__, mCameraId, strerror(-res), res);
1468 return res;
1469 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001470 res = updateCaptureRequest(k.mParameters);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001471 if (res != OK) {
1472 ALOGE("%s: Camera %d: Unable to update capture request: %s (%d)",
1473 __FUNCTION__, mCameraId, strerror(-res), res);
1474 return res;
1475 }
1476
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001477 res = updateRecordingRequest(k.mParameters);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001478 if (res != OK) {
1479 ALOGE("%s: Camera %d: Unable to update recording request: %s (%d)",
1480 __FUNCTION__, mCameraId, strerror(-res), res);
1481 return res;
1482 }
1483
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001484 if (mState == PREVIEW) {
1485 res = mDevice->setStreamingRequest(mPreviewRequest);
1486 if (res != OK) {
1487 ALOGE("%s: Camera %d: Error streaming new preview request: %s (%d)",
1488 __FUNCTION__, mCameraId, strerror(-res), res);
1489 return res;
1490 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001491 } else if (mState == RECORD || mState == VIDEO_SNAPSHOT) {
1492 res = mDevice->setStreamingRequest(mRecordingRequest);
1493 if (res != OK) {
1494 ALOGE("%s: Camera %d: Error streaming new record request: %s (%d)",
1495 __FUNCTION__, mCameraId, strerror(-res), res);
1496 return res;
1497 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001498 }
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001499
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001500 k.mParameters.paramsFlattened = params;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001501
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001502 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001503}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001504
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001505String8 Camera2Client::getParameters() const {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001506 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001507 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001508 if ( checkPid(__FUNCTION__) != OK) return String8();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001509
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001510 LockedParameters::ReadKey k(mParameters);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001511
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001512 // TODO: Deal with focus distances
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001513 return k.mParameters.paramsFlattened;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001514}
1515
1516status_t Camera2Client::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001517 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001518 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001519 status_t res;
1520 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001521
1522 ALOGV("%s: Camera %d: Command %d (%d, %d)", __FUNCTION__, mCameraId,
1523 cmd, arg1, arg2);
1524
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001525 switch (cmd) {
1526 case CAMERA_CMD_START_SMOOTH_ZOOM:
1527 return commandStartSmoothZoomL();
1528 case CAMERA_CMD_STOP_SMOOTH_ZOOM:
1529 return commandStopSmoothZoomL();
1530 case CAMERA_CMD_SET_DISPLAY_ORIENTATION:
1531 return commandSetDisplayOrientationL(arg1);
1532 case CAMERA_CMD_ENABLE_SHUTTER_SOUND:
1533 return commandEnableShutterSoundL(arg1 == 1);
1534 case CAMERA_CMD_PLAY_RECORDING_SOUND:
1535 return commandPlayRecordingSoundL();
1536 case CAMERA_CMD_START_FACE_DETECTION:
1537 return commandStartFaceDetectionL(arg1);
1538 case CAMERA_CMD_STOP_FACE_DETECTION:
1539 return commandStopFaceDetectionL();
1540 case CAMERA_CMD_ENABLE_FOCUS_MOVE_MSG:
1541 return commandEnableFocusMoveMsgL(arg1 == 1);
1542 case CAMERA_CMD_PING:
1543 return commandPingL();
1544 case CAMERA_CMD_SET_VIDEO_BUFFER_COUNT:
1545 return commandSetVideoBufferCountL(arg1);
1546 default:
1547 ALOGE("%s: Unknown command %d (arguments %d, %d)",
1548 __FUNCTION__, cmd, arg1, arg2);
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001549 return BAD_VALUE;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001550 }
1551}
James Dong983cf232012-08-01 16:39:55 -07001552
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001553status_t Camera2Client::commandStartSmoothZoomL() {
1554 ALOGE("%s: Unimplemented!", __FUNCTION__);
1555 return OK;
1556}
James Dong983cf232012-08-01 16:39:55 -07001557
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001558status_t Camera2Client::commandStopSmoothZoomL() {
1559 ALOGE("%s: Unimplemented!", __FUNCTION__);
1560 return OK;
1561}
James Dong983cf232012-08-01 16:39:55 -07001562
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001563status_t Camera2Client::commandSetDisplayOrientationL(int degrees) {
1564 LockedParameters::Key k(mParameters);
1565 int transform = degToTransform(degrees,
1566 mCameraFacing == CAMERA_FACING_FRONT);
1567 if (transform == -1) {
1568 ALOGE("%s: Camera %d: Error setting %d as display orientation value",
1569 __FUNCTION__, mCameraId, degrees);
1570 return BAD_VALUE;
1571 }
1572 if (transform != k.mParameters.previewTransform &&
1573 mPreviewStreamId != NO_STREAM) {
1574 mDevice->setStreamTransform(mPreviewStreamId, transform);
1575 }
1576 k.mParameters.previewTransform = transform;
1577 return OK;
1578}
1579
1580status_t Camera2Client::commandEnableShutterSoundL(bool enable) {
1581 LockedParameters::Key k(mParameters);
1582 if (enable) {
1583 k.mParameters.playShutterSound = true;
James Dong983cf232012-08-01 16:39:55 -07001584 return OK;
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001585 }
1586
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001587 // Disabling shutter sound may not be allowed. In that case only
1588 // allow the mediaserver process to disable the sound.
1589 char value[PROPERTY_VALUE_MAX];
1590 property_get("ro.camera.sound.forced", value, "0");
1591 if (strncmp(value, "0", 2) != 0) {
1592 // Disabling shutter sound is not allowed. Deny if the current
1593 // process is not mediaserver.
1594 if (getCallingPid() != getpid()) {
1595 ALOGE("Failed to disable shutter sound. Permission denied (pid %d)",
1596 getCallingPid());
1597 return PERMISSION_DENIED;
1598 }
1599 }
1600
1601 k.mParameters.playShutterSound = false;
1602 return OK;
1603}
1604
1605status_t Camera2Client::commandPlayRecordingSoundL() {
1606 mCameraService->playSound(CameraService::SOUND_RECORDING);
1607 return OK;
1608}
1609
1610status_t Camera2Client::commandStartFaceDetectionL(int type) {
1611 ALOGE("%s: Unimplemented!", __FUNCTION__);
1612 return OK;
1613}
1614
1615status_t Camera2Client::commandStopFaceDetectionL() {
1616 ALOGE("%s: Unimplemented!", __FUNCTION__);
1617 return OK;
1618}
1619
1620status_t Camera2Client::commandEnableFocusMoveMsgL(bool enable) {
1621 ALOGE("%s: Unimplemented!", __FUNCTION__);
1622 return OK;
1623}
1624
1625status_t Camera2Client::commandPingL() {
1626 // Always ping back if access is proper and device is alive
1627 if (mState != DISCONNECTED) {
1628 return OK;
1629 } else {
1630 return NO_INIT;
1631 }
1632}
1633
1634status_t Camera2Client::commandSetVideoBufferCountL(size_t count) {
1635 if (recordingEnabled()) {
1636 ALOGE("%s: Camera %d: Error setting video buffer count after "
1637 "recording was started", __FUNCTION__, mCameraId);
1638 return INVALID_OPERATION;
1639 }
1640
1641 // 32 is the current upper limit on the video buffer count for BufferQueue
1642 if (count > 32) {
1643 ALOGE("%s: Camera %d: Error setting %d as video buffer count value",
1644 __FUNCTION__, mCameraId, count);
1645 return BAD_VALUE;
1646 }
1647
1648 // Need to reallocate memory for heap
1649 if (mRecordingHeapCount != count) {
1650 if (mRecordingHeap != 0) {
1651 mRecordingHeap.clear();
1652 mRecordingHeap = NULL;
1653 }
1654 mRecordingHeapCount = count;
1655 }
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001656
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001657 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001658}
1659
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001660/** Device-related methods */
1661
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -07001662void Camera2Client::notifyError(int errorCode, int arg1, int arg2) {
1663 ALOGE("Error condition %d reported by HAL, arguments %d, %d", errorCode, arg1, arg2);
1664}
1665
1666void Camera2Client::notifyShutter(int frameNumber, nsecs_t timestamp) {
1667 ALOGV("%s: Shutter notification for frame %d at time %lld", __FUNCTION__,
1668 frameNumber, timestamp);
1669}
1670
1671void Camera2Client::notifyAutoFocus(uint8_t newState, int triggerId) {
1672 ALOGV("%s: Autofocus state now %d, last trigger %d",
1673 __FUNCTION__, newState, triggerId);
1674}
1675
1676void Camera2Client::notifyAutoExposure(uint8_t newState, int triggerId) {
1677 ALOGV("%s: Autoexposure state now %d, last trigger %d",
1678 __FUNCTION__, newState, triggerId);
1679}
1680
1681void Camera2Client::notifyAutoWhitebalance(uint8_t newState, int triggerId) {
1682 ALOGV("%s: Auto-whitebalance state now %d, last trigger %d",
1683 __FUNCTION__, newState, triggerId);
1684}
1685
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001686void Camera2Client::onCaptureAvailable() {
1687 ATRACE_CALL();
1688 status_t res;
1689 sp<ICameraClient> currentClient;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001690 ALOGV("%s: Camera %d: Still capture available", __FUNCTION__, mCameraId);
1691
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001692 CpuConsumer::LockedBuffer imgBuffer;
1693 {
1694 Mutex::Autolock icl(mICameraLock);
1695
1696 // TODO: Signal errors here upstream
1697 if (mState != STILL_CAPTURE && mState != VIDEO_SNAPSHOT) {
1698 ALOGE("%s: Camera %d: Still image produced unexpectedly!",
1699 __FUNCTION__, mCameraId);
1700 return;
1701 }
1702
1703 res = mCaptureConsumer->lockNextBuffer(&imgBuffer);
1704 if (res != OK) {
1705 ALOGE("%s: Camera %d: Error receiving still image buffer: %s (%d)",
1706 __FUNCTION__, mCameraId, strerror(-res), res);
1707 return;
1708 }
1709
1710 if (imgBuffer.format != HAL_PIXEL_FORMAT_BLOB) {
1711 ALOGE("%s: Camera %d: Unexpected format for still image: "
1712 "%x, expected %x", __FUNCTION__, mCameraId,
1713 imgBuffer.format,
1714 HAL_PIXEL_FORMAT_BLOB);
1715 mCaptureConsumer->unlockBuffer(imgBuffer);
1716 return;
1717 }
1718
1719 // TODO: Optimize this to avoid memcopy
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001720 void* captureMemory = mCaptureHeap->mHeap->getBase();
1721 size_t size = mCaptureHeap->mHeap->getSize();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001722 memcpy(captureMemory, imgBuffer.data, size);
1723
1724 mCaptureConsumer->unlockBuffer(imgBuffer);
1725
1726 currentClient = mCameraClient;
1727 switch (mState) {
1728 case STILL_CAPTURE:
1729 mState = STOPPED;
1730 break;
1731 case VIDEO_SNAPSHOT:
1732 mState = RECORD;
1733 break;
1734 default:
1735 ALOGE("%s: Camera %d: Unexpected state %d", __FUNCTION__,
1736 mCameraId, mState);
1737 break;
1738 }
1739 }
1740 // Call outside mICameraLock to allow re-entrancy from notification
1741 if (currentClient != 0) {
1742 currentClient->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001743 mCaptureHeap->mBuffers[0], NULL);
1744 }
1745}
1746
1747void Camera2Client::onRecordingFrameAvailable() {
1748 ATRACE_CALL();
1749 status_t res;
1750 sp<ICameraClient> currentClient;
1751 size_t heapIdx = 0;
1752 nsecs_t timestamp;
1753 {
1754 Mutex::Autolock icl(mICameraLock);
1755 // TODO: Signal errors here upstream
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001756 bool discardData = false;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001757 if (mState != RECORD && mState != VIDEO_SNAPSHOT) {
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001758 ALOGV("%s: Camera %d: Discarding recording image buffers received after "
1759 "recording done",
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001760 __FUNCTION__, mCameraId);
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001761 discardData = true;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001762 }
1763
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001764 buffer_handle_t imgBuffer;
1765 res = mRecordingConsumer->getNextBuffer(&imgBuffer, &timestamp);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001766 if (res != OK) {
1767 ALOGE("%s: Camera %d: Error receiving recording buffer: %s (%d)",
1768 __FUNCTION__, mCameraId, strerror(-res), res);
1769 return;
1770 }
1771
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001772 if (discardData) {
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001773 mRecordingConsumer->freeBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001774 return;
1775 }
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001776
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001777 if (mRecordingHeap == 0) {
1778 const size_t bufferSize = 4 + sizeof(buffer_handle_t);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001779 ALOGV("%s: Camera %d: Creating recording heap with %d buffers of "
1780 "size %d bytes", __FUNCTION__, mCameraId,
James Dong983cf232012-08-01 16:39:55 -07001781 mRecordingHeapCount, bufferSize);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001782 if (mRecordingHeap != 0) {
1783 ALOGV("%s: Camera %d: Previous heap has size %d "
1784 "(new will be %d) bytes", __FUNCTION__, mCameraId,
1785 mRecordingHeap->mHeap->getSize(),
James Dong983cf232012-08-01 16:39:55 -07001786 bufferSize * mRecordingHeapCount);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001787 }
1788 // Need to allocate memory for heap
1789 mRecordingHeap.clear();
1790
James Dong983cf232012-08-01 16:39:55 -07001791 mRecordingHeap = new Camera2Heap(bufferSize, mRecordingHeapCount,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001792 "Camera2Client::RecordingHeap");
1793 if (mRecordingHeap->mHeap->getSize() == 0) {
1794 ALOGE("%s: Camera %d: Unable to allocate memory for recording",
1795 __FUNCTION__, mCameraId);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001796 mRecordingConsumer->freeBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001797 return;
1798 }
1799 mRecordingHeapHead = 0;
James Dong983cf232012-08-01 16:39:55 -07001800 mRecordingHeapFree = mRecordingHeapCount;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001801 }
1802
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001803 if ( mRecordingHeapFree == 0) {
1804 ALOGE("%s: Camera %d: No free recording buffers, dropping frame",
1805 __FUNCTION__, mCameraId);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001806 mRecordingConsumer->freeBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001807 return;
1808 }
1809 heapIdx = mRecordingHeapHead;
James Dong983cf232012-08-01 16:39:55 -07001810 mRecordingHeapHead = (mRecordingHeapHead + 1) % mRecordingHeapCount;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001811 mRecordingHeapFree--;
1812
1813 ALOGV("%s: Camera %d: Timestamp %lld",
1814 __FUNCTION__, mCameraId, timestamp);
1815
1816 ssize_t offset;
1817 size_t size;
1818 sp<IMemoryHeap> heap =
1819 mRecordingHeap->mBuffers[heapIdx]->getMemory(&offset,
1820 &size);
1821
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001822 uint8_t *data = (uint8_t*)heap->getBase() + offset;
1823 uint32_t type = kMetadataBufferTypeGrallocSource;
1824 memcpy(data, &type, 4);
1825 memcpy(data + 4, &imgBuffer, sizeof(buffer_handle_t));
1826 ALOGV("%s: Camera %d: Sending out buffer_handle_t %p",
Eino-Ville Talvala803cbf62012-07-25 15:23:36 -07001827 __FUNCTION__, mCameraId, imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001828 currentClient = mCameraClient;
1829 }
1830 // Call outside mICameraLock to allow re-entrancy from notification
1831 if (currentClient != 0) {
1832 currentClient->dataCallbackTimestamp(timestamp,
1833 CAMERA_MSG_VIDEO_FRAME,
1834 mRecordingHeap->mBuffers[heapIdx]);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001835 }
1836}
1837
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001838camera_metadata_entry_t Camera2Client::staticInfo(uint32_t tag,
1839 size_t minCount, size_t maxCount) {
1840 status_t res;
1841 camera_metadata_entry_t entry;
1842 res = find_camera_metadata_entry(mDevice->info(),
1843 tag,
1844 &entry);
1845 if (CC_UNLIKELY( res != OK )) {
1846 const char* tagSection = get_camera_metadata_section_name(tag);
1847 if (tagSection == NULL) tagSection = "<unknown>";
1848 const char* tagName = get_camera_metadata_tag_name(tag);
1849 if (tagName == NULL) tagName = "<unknown>";
1850
1851 ALOGE("Error finding static metadata entry '%s.%s' (%x): %s (%d)",
1852 tagSection, tagName, tag, strerror(-res), res);
1853 entry.count = 0;
1854 entry.data.u8 = NULL;
1855 } else if (CC_UNLIKELY(
1856 (minCount != 0 && entry.count < minCount) ||
1857 (maxCount != 0 && entry.count > maxCount) ) ) {
1858 const char* tagSection = get_camera_metadata_section_name(tag);
1859 if (tagSection == NULL) tagSection = "<unknown>";
1860 const char* tagName = get_camera_metadata_tag_name(tag);
1861 if (tagName == NULL) tagName = "<unknown>";
1862 ALOGE("Malformed static metadata entry '%s.%s' (%x):"
1863 "Expected between %d and %d values, but got %d values",
1864 tagSection, tagName, tag, minCount, maxCount, entry.count);
1865 entry.count = 0;
1866 entry.data.u8 = NULL;
1867 }
1868
1869 return entry;
1870}
1871
1872/** Utility methods */
1873
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001874
1875status_t Camera2Client::buildDefaultParameters() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001876 ATRACE_CALL();
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001877 LockedParameters::Key k(mParameters);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001878
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001879 status_t res;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001880 CameraParameters params;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001881
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001882 camera_metadata_entry_t availableProcessedSizes =
1883 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES, 2);
1884 if (!availableProcessedSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001885
1886 // TODO: Pick more intelligently
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001887 k.mParameters.previewWidth = availableProcessedSizes.data.i32[0];
1888 k.mParameters.previewHeight = availableProcessedSizes.data.i32[1];
1889 k.mParameters.videoWidth = k.mParameters.previewWidth;
1890 k.mParameters.videoHeight = k.mParameters.previewHeight;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001891
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001892 params.setPreviewSize(k.mParameters.previewWidth, k.mParameters.previewHeight);
1893 params.setVideoSize(k.mParameters.videoWidth, k.mParameters.videoHeight);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001894 params.set(CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO,
1895 String8::format("%dx%d",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001896 k.mParameters.previewWidth, k.mParameters.previewHeight));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001897 {
1898 String8 supportedPreviewSizes;
1899 for (size_t i=0; i < availableProcessedSizes.count; i += 2) {
1900 if (i != 0) supportedPreviewSizes += ",";
1901 supportedPreviewSizes += String8::format("%dx%d",
1902 availableProcessedSizes.data.i32[i],
1903 availableProcessedSizes.data.i32[i+1]);
1904 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001905 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001906 supportedPreviewSizes);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001907 params.set(CameraParameters::KEY_SUPPORTED_VIDEO_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001908 supportedPreviewSizes);
1909 }
1910
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001911 camera_metadata_entry_t availableFpsRanges =
1912 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
1913 if (!availableFpsRanges.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001914
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001915 k.mParameters.previewFpsRange[0] = availableFpsRanges.data.i32[0];
1916 k.mParameters.previewFpsRange[1] = availableFpsRanges.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001917
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001918 params.set(CameraParameters::KEY_PREVIEW_FPS_RANGE,
1919 String8::format("%d,%d",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001920 k.mParameters.previewFpsRange[0],
1921 k.mParameters.previewFpsRange[1]));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001922
1923 {
1924 String8 supportedPreviewFpsRange;
1925 for (size_t i=0; i < availableFpsRanges.count; i += 2) {
1926 if (i != 0) supportedPreviewFpsRange += ",";
1927 supportedPreviewFpsRange += String8::format("(%d,%d)",
1928 availableFpsRanges.data.i32[i],
1929 availableFpsRanges.data.i32[i+1]);
1930 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001931 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001932 supportedPreviewFpsRange);
1933 }
1934
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001935 k.mParameters.previewFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001936 params.set(CameraParameters::KEY_PREVIEW_FORMAT,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001937 formatEnumToString(k.mParameters.previewFormat)); // NV21
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001938
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001939 k.mParameters.previewTransform = degToTransform(0,
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001940 mCameraFacing == CAMERA_FACING_FRONT);
1941
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001942 camera_metadata_entry_t availableFormats =
1943 staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
1944
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001945 {
1946 String8 supportedPreviewFormats;
1947 bool addComma = false;
1948 for (size_t i=0; i < availableFormats.count; i++) {
1949 if (addComma) supportedPreviewFormats += ",";
1950 addComma = true;
1951 switch (availableFormats.data.i32[i]) {
1952 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001953 supportedPreviewFormats +=
1954 CameraParameters::PIXEL_FORMAT_YUV422SP;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001955 break;
1956 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001957 supportedPreviewFormats +=
1958 CameraParameters::PIXEL_FORMAT_YUV420SP;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001959 break;
1960 case HAL_PIXEL_FORMAT_YCbCr_422_I:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001961 supportedPreviewFormats +=
1962 CameraParameters::PIXEL_FORMAT_YUV422I;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001963 break;
1964 case HAL_PIXEL_FORMAT_YV12:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001965 supportedPreviewFormats +=
1966 CameraParameters::PIXEL_FORMAT_YUV420P;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001967 break;
1968 case HAL_PIXEL_FORMAT_RGB_565:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001969 supportedPreviewFormats +=
1970 CameraParameters::PIXEL_FORMAT_RGB565;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001971 break;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001972 case HAL_PIXEL_FORMAT_RGBA_8888:
1973 supportedPreviewFormats +=
1974 CameraParameters::PIXEL_FORMAT_RGBA8888;
1975 break;
1976 // Not advertizing JPEG, RAW_SENSOR, etc, for preview formats
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001977 case HAL_PIXEL_FORMAT_RAW_SENSOR:
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001978 case HAL_PIXEL_FORMAT_BLOB:
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001979 addComma = false;
1980 break;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001981
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001982 default:
1983 ALOGW("%s: Camera %d: Unknown preview format: %x",
1984 __FUNCTION__, mCameraId, availableFormats.data.i32[i]);
1985 addComma = false;
1986 break;
1987 }
1988 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001989 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001990 supportedPreviewFormats);
1991 }
1992
1993 // PREVIEW_FRAME_RATE / SUPPORTED_PREVIEW_FRAME_RATES are deprecated, but
1994 // still have to do something sane for them
1995
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001996 params.set(CameraParameters::KEY_PREVIEW_FRAME_RATE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001997 k.mParameters.previewFpsRange[0]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001998
1999 {
2000 String8 supportedPreviewFrameRates;
2001 for (size_t i=0; i < availableFpsRanges.count; i += 2) {
2002 if (i != 0) supportedPreviewFrameRates += ",";
2003 supportedPreviewFrameRates += String8::format("%d",
2004 availableFpsRanges.data.i32[i]);
2005 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002006 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002007 supportedPreviewFrameRates);
2008 }
2009
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002010 camera_metadata_entry_t availableJpegSizes =
2011 staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES, 2);
2012 if (!availableJpegSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002013
2014 // TODO: Pick maximum
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002015 k.mParameters.pictureWidth = availableJpegSizes.data.i32[0];
2016 k.mParameters.pictureHeight = availableJpegSizes.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002017
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002018 params.setPictureSize(k.mParameters.pictureWidth,
2019 k.mParameters.pictureHeight);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002020
2021 {
2022 String8 supportedPictureSizes;
2023 for (size_t i=0; i < availableJpegSizes.count; i += 2) {
2024 if (i != 0) supportedPictureSizes += ",";
2025 supportedPictureSizes += String8::format("%dx%d",
2026 availableJpegSizes.data.i32[i],
2027 availableJpegSizes.data.i32[i+1]);
2028 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002029 params.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002030 supportedPictureSizes);
2031 }
2032
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002033 params.setPictureFormat(CameraParameters::PIXEL_FORMAT_JPEG);
2034 params.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS,
2035 CameraParameters::PIXEL_FORMAT_JPEG);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002036
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002037 camera_metadata_entry_t availableJpegThumbnailSizes =
2038 staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES, 2);
2039 if (!availableJpegThumbnailSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002040
2041 // TODO: Pick default thumbnail size sensibly
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002042 k.mParameters.jpegThumbSize[0] = availableJpegThumbnailSizes.data.i32[0];
2043 k.mParameters.jpegThumbSize[1] = availableJpegThumbnailSizes.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002044
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002045 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002046 k.mParameters.jpegThumbSize[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002047 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002048 k.mParameters.jpegThumbSize[1]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002049
2050 {
2051 String8 supportedJpegThumbSizes;
2052 for (size_t i=0; i < availableJpegThumbnailSizes.count; i += 2) {
2053 if (i != 0) supportedJpegThumbSizes += ",";
2054 supportedJpegThumbSizes += String8::format("%dx%d",
2055 availableJpegThumbnailSizes.data.i32[i],
2056 availableJpegThumbnailSizes.data.i32[i+1]);
2057 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002058 params.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002059 supportedJpegThumbSizes);
2060 }
2061
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002062 k.mParameters.jpegThumbQuality = 90;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002063 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002064 k.mParameters.jpegThumbQuality);
2065 k.mParameters.jpegQuality = 90;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002066 params.set(CameraParameters::KEY_JPEG_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002067 k.mParameters.jpegQuality);
2068 k.mParameters.jpegRotation = 0;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002069 params.set(CameraParameters::KEY_ROTATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002070 k.mParameters.jpegRotation);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002071
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002072 k.mParameters.gpsEnabled = false;
2073 k.mParameters.gpsProcessingMethod = "unknown";
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002074 // GPS fields in CameraParameters are not set by implementation
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002075
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002076 k.mParameters.wbMode = ANDROID_CONTROL_AWB_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002077 params.set(CameraParameters::KEY_WHITE_BALANCE,
2078 CameraParameters::WHITE_BALANCE_AUTO);
2079
2080 camera_metadata_entry_t availableWhiteBalanceModes =
2081 staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002082 {
2083 String8 supportedWhiteBalance;
2084 bool addComma = false;
2085 for (size_t i=0; i < availableWhiteBalanceModes.count; i++) {
2086 if (addComma) supportedWhiteBalance += ",";
2087 addComma = true;
2088 switch (availableWhiteBalanceModes.data.u8[i]) {
2089 case ANDROID_CONTROL_AWB_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002090 supportedWhiteBalance +=
2091 CameraParameters::WHITE_BALANCE_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002092 break;
2093 case ANDROID_CONTROL_AWB_INCANDESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002094 supportedWhiteBalance +=
2095 CameraParameters::WHITE_BALANCE_INCANDESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002096 break;
2097 case ANDROID_CONTROL_AWB_FLUORESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002098 supportedWhiteBalance +=
2099 CameraParameters::WHITE_BALANCE_FLUORESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002100 break;
2101 case ANDROID_CONTROL_AWB_WARM_FLUORESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002102 supportedWhiteBalance +=
2103 CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002104 break;
2105 case ANDROID_CONTROL_AWB_DAYLIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002106 supportedWhiteBalance +=
2107 CameraParameters::WHITE_BALANCE_DAYLIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002108 break;
2109 case ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002110 supportedWhiteBalance +=
2111 CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002112 break;
2113 case ANDROID_CONTROL_AWB_TWILIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002114 supportedWhiteBalance +=
2115 CameraParameters::WHITE_BALANCE_TWILIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002116 break;
2117 case ANDROID_CONTROL_AWB_SHADE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002118 supportedWhiteBalance +=
2119 CameraParameters::WHITE_BALANCE_SHADE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002120 break;
2121 // Skipping values not mappable to v1 API
2122 case ANDROID_CONTROL_AWB_OFF:
2123 addComma = false;
2124 break;
2125 default:
2126 ALOGW("%s: Camera %d: Unknown white balance value: %d",
2127 __FUNCTION__, mCameraId,
2128 availableWhiteBalanceModes.data.u8[i]);
2129 addComma = false;
2130 break;
2131 }
2132 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002133 params.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002134 supportedWhiteBalance);
2135 }
2136
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002137 k.mParameters.effectMode = ANDROID_CONTROL_EFFECT_OFF;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002138 params.set(CameraParameters::KEY_EFFECT,
2139 CameraParameters::EFFECT_NONE);
2140
2141 camera_metadata_entry_t availableEffects =
2142 staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
2143 if (!availableEffects.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002144 {
2145 String8 supportedEffects;
2146 bool addComma = false;
2147 for (size_t i=0; i < availableEffects.count; i++) {
2148 if (addComma) supportedEffects += ",";
2149 addComma = true;
2150 switch (availableEffects.data.u8[i]) {
2151 case ANDROID_CONTROL_EFFECT_OFF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002152 supportedEffects +=
2153 CameraParameters::EFFECT_NONE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002154 break;
2155 case ANDROID_CONTROL_EFFECT_MONO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002156 supportedEffects +=
2157 CameraParameters::EFFECT_MONO;
2158 break;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002159 case ANDROID_CONTROL_EFFECT_NEGATIVE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002160 supportedEffects +=
2161 CameraParameters::EFFECT_NEGATIVE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002162 break;
2163 case ANDROID_CONTROL_EFFECT_SOLARIZE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002164 supportedEffects +=
2165 CameraParameters::EFFECT_SOLARIZE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002166 break;
2167 case ANDROID_CONTROL_EFFECT_SEPIA:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002168 supportedEffects +=
2169 CameraParameters::EFFECT_SEPIA;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002170 break;
2171 case ANDROID_CONTROL_EFFECT_POSTERIZE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002172 supportedEffects +=
2173 CameraParameters::EFFECT_POSTERIZE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002174 break;
2175 case ANDROID_CONTROL_EFFECT_WHITEBOARD:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002176 supportedEffects +=
2177 CameraParameters::EFFECT_WHITEBOARD;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002178 break;
2179 case ANDROID_CONTROL_EFFECT_BLACKBOARD:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002180 supportedEffects +=
2181 CameraParameters::EFFECT_BLACKBOARD;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002182 break;
2183 case ANDROID_CONTROL_EFFECT_AQUA:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002184 supportedEffects +=
2185 CameraParameters::EFFECT_AQUA;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002186 break;
2187 default:
2188 ALOGW("%s: Camera %d: Unknown effect value: %d",
2189 __FUNCTION__, mCameraId, availableEffects.data.u8[i]);
2190 addComma = false;
2191 break;
2192 }
2193 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002194 params.set(CameraParameters::KEY_SUPPORTED_EFFECTS, supportedEffects);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002195 }
2196
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002197 k.mParameters.antibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002198 params.set(CameraParameters::KEY_ANTIBANDING,
2199 CameraParameters::ANTIBANDING_AUTO);
2200
2201 camera_metadata_entry_t availableAntibandingModes =
2202 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
2203 if (!availableAntibandingModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002204 {
2205 String8 supportedAntibanding;
2206 bool addComma = false;
2207 for (size_t i=0; i < availableAntibandingModes.count; i++) {
2208 if (addComma) supportedAntibanding += ",";
2209 addComma = true;
2210 switch (availableAntibandingModes.data.u8[i]) {
2211 case ANDROID_CONTROL_AE_ANTIBANDING_OFF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002212 supportedAntibanding +=
2213 CameraParameters::ANTIBANDING_OFF;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002214 break;
2215 case ANDROID_CONTROL_AE_ANTIBANDING_50HZ:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002216 supportedAntibanding +=
2217 CameraParameters::ANTIBANDING_50HZ;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002218 break;
2219 case ANDROID_CONTROL_AE_ANTIBANDING_60HZ:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002220 supportedAntibanding +=
2221 CameraParameters::ANTIBANDING_60HZ;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002222 break;
2223 case ANDROID_CONTROL_AE_ANTIBANDING_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002224 supportedAntibanding +=
2225 CameraParameters::ANTIBANDING_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002226 break;
2227 default:
2228 ALOGW("%s: Camera %d: Unknown antibanding value: %d",
2229 __FUNCTION__, mCameraId,
2230 availableAntibandingModes.data.u8[i]);
2231 addComma = false;
2232 break;
2233 }
2234 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002235 params.set(CameraParameters::KEY_SUPPORTED_ANTIBANDING,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002236 supportedAntibanding);
2237 }
2238
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002239 k.mParameters.sceneMode = ANDROID_CONTROL_OFF;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002240 params.set(CameraParameters::KEY_SCENE_MODE,
2241 CameraParameters::SCENE_MODE_AUTO);
2242
2243 camera_metadata_entry_t availableSceneModes =
2244 staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
2245 if (!availableSceneModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002246 {
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002247 String8 supportedSceneModes(CameraParameters::SCENE_MODE_AUTO);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002248 bool addComma = true;
2249 bool noSceneModes = false;
2250 for (size_t i=0; i < availableSceneModes.count; i++) {
2251 if (addComma) supportedSceneModes += ",";
2252 addComma = true;
2253 switch (availableSceneModes.data.u8[i]) {
2254 case ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED:
2255 noSceneModes = true;
2256 break;
2257 case ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY:
2258 // Not in old API
2259 addComma = false;
2260 break;
2261 case ANDROID_CONTROL_SCENE_MODE_ACTION:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002262 supportedSceneModes +=
2263 CameraParameters::SCENE_MODE_ACTION;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002264 break;
2265 case ANDROID_CONTROL_SCENE_MODE_PORTRAIT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002266 supportedSceneModes +=
2267 CameraParameters::SCENE_MODE_PORTRAIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002268 break;
2269 case ANDROID_CONTROL_SCENE_MODE_LANDSCAPE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002270 supportedSceneModes +=
2271 CameraParameters::SCENE_MODE_LANDSCAPE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002272 break;
2273 case ANDROID_CONTROL_SCENE_MODE_NIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002274 supportedSceneModes +=
2275 CameraParameters::SCENE_MODE_NIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002276 break;
2277 case ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002278 supportedSceneModes +=
2279 CameraParameters::SCENE_MODE_NIGHT_PORTRAIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002280 break;
2281 case ANDROID_CONTROL_SCENE_MODE_THEATRE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002282 supportedSceneModes +=
2283 CameraParameters::SCENE_MODE_THEATRE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002284 break;
2285 case ANDROID_CONTROL_SCENE_MODE_BEACH:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002286 supportedSceneModes +=
2287 CameraParameters::SCENE_MODE_BEACH;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002288 break;
2289 case ANDROID_CONTROL_SCENE_MODE_SNOW:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002290 supportedSceneModes +=
2291 CameraParameters::SCENE_MODE_SNOW;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002292 break;
2293 case ANDROID_CONTROL_SCENE_MODE_SUNSET:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002294 supportedSceneModes +=
2295 CameraParameters::SCENE_MODE_SUNSET;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002296 break;
2297 case ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002298 supportedSceneModes +=
2299 CameraParameters::SCENE_MODE_STEADYPHOTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002300 break;
2301 case ANDROID_CONTROL_SCENE_MODE_FIREWORKS:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002302 supportedSceneModes +=
2303 CameraParameters::SCENE_MODE_FIREWORKS;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002304 break;
2305 case ANDROID_CONTROL_SCENE_MODE_SPORTS:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002306 supportedSceneModes +=
2307 CameraParameters::SCENE_MODE_SPORTS;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002308 break;
2309 case ANDROID_CONTROL_SCENE_MODE_PARTY:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002310 supportedSceneModes +=
2311 CameraParameters::SCENE_MODE_PARTY;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002312 break;
2313 case ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002314 supportedSceneModes +=
2315 CameraParameters::SCENE_MODE_CANDLELIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002316 break;
2317 case ANDROID_CONTROL_SCENE_MODE_BARCODE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002318 supportedSceneModes +=
2319 CameraParameters::SCENE_MODE_BARCODE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002320 break;
2321 default:
2322 ALOGW("%s: Camera %d: Unknown scene mode value: %d",
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002323 __FUNCTION__, mCameraId,
2324 availableSceneModes.data.u8[i]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002325 addComma = false;
2326 break;
2327 }
2328 }
2329 if (!noSceneModes) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002330 params.set(CameraParameters::KEY_SUPPORTED_SCENE_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002331 supportedSceneModes);
2332 }
2333 }
2334
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002335 camera_metadata_entry_t flashAvailable =
2336 staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
2337 if (!flashAvailable.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002338
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002339 camera_metadata_entry_t availableAeModes =
2340 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
2341 if (!availableAeModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002342
2343 if (flashAvailable.data.u8[0]) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002344 k.mParameters.flashMode = Parameters::FLASH_MODE_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002345 params.set(CameraParameters::KEY_FLASH_MODE,
2346 CameraParameters::FLASH_MODE_AUTO);
2347
2348 String8 supportedFlashModes(CameraParameters::FLASH_MODE_OFF);
2349 supportedFlashModes = supportedFlashModes +
2350 "," + CameraParameters::FLASH_MODE_AUTO +
2351 "," + CameraParameters::FLASH_MODE_ON +
2352 "," + CameraParameters::FLASH_MODE_TORCH;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002353 for (size_t i=0; i < availableAeModes.count; i++) {
2354 if (availableAeModes.data.u8[i] ==
2355 ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002356 supportedFlashModes = supportedFlashModes + "," +
2357 CameraParameters::FLASH_MODE_RED_EYE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002358 break;
2359 }
2360 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002361 params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002362 supportedFlashModes);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002363 } else {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002364 k.mParameters.flashMode = Parameters::FLASH_MODE_OFF;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002365 params.set(CameraParameters::KEY_FLASH_MODE,
2366 CameraParameters::FLASH_MODE_OFF);
2367 params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
2368 CameraParameters::FLASH_MODE_OFF);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002369 }
2370
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002371 camera_metadata_entry_t minFocusDistance =
2372 staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE, 1, 1);
2373 if (!minFocusDistance.count) return NO_INIT;
2374
2375 camera_metadata_entry_t availableAfModes =
2376 staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
2377 if (!availableAfModes.count) return NO_INIT;
2378
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002379 if (minFocusDistance.data.f[0] == 0) {
2380 // Fixed-focus lens
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002381 k.mParameters.focusMode = Parameters::FOCUS_MODE_FIXED;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002382 params.set(CameraParameters::KEY_FOCUS_MODE,
2383 CameraParameters::FOCUS_MODE_FIXED);
2384 params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
2385 CameraParameters::FOCUS_MODE_FIXED);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002386 } else {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002387 k.mParameters.focusMode = Parameters::FOCUS_MODE_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002388 params.set(CameraParameters::KEY_FOCUS_MODE,
2389 CameraParameters::FOCUS_MODE_AUTO);
2390 String8 supportedFocusModes(CameraParameters::FOCUS_MODE_FIXED);
2391 supportedFocusModes = supportedFocusModes + "," +
2392 CameraParameters::FOCUS_MODE_INFINITY;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002393 bool addComma = true;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002394
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002395 for (size_t i=0; i < availableAfModes.count; i++) {
2396 if (addComma) supportedFocusModes += ",";
2397 addComma = true;
2398 switch (availableAfModes.data.u8[i]) {
2399 case ANDROID_CONTROL_AF_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002400 supportedFocusModes +=
2401 CameraParameters::FOCUS_MODE_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002402 break;
2403 case ANDROID_CONTROL_AF_MACRO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002404 supportedFocusModes +=
2405 CameraParameters::FOCUS_MODE_MACRO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002406 break;
2407 case ANDROID_CONTROL_AF_CONTINUOUS_VIDEO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002408 supportedFocusModes +=
2409 CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002410 break;
2411 case ANDROID_CONTROL_AF_CONTINUOUS_PICTURE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002412 supportedFocusModes +=
2413 CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002414 break;
2415 case ANDROID_CONTROL_AF_EDOF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002416 supportedFocusModes +=
2417 CameraParameters::FOCUS_MODE_EDOF;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002418 break;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002419 // Not supported in old API
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002420 case ANDROID_CONTROL_AF_OFF:
2421 addComma = false;
2422 break;
2423 default:
2424 ALOGW("%s: Camera %d: Unknown AF mode value: %d",
2425 __FUNCTION__, mCameraId, availableAfModes.data.u8[i]);
2426 addComma = false;
2427 break;
2428 }
2429 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002430 params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002431 supportedFocusModes);
2432 }
2433
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002434 camera_metadata_entry_t max3aRegions =
2435 staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1);
2436 if (!max3aRegions.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002437
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002438 params.set(CameraParameters::KEY_MAX_NUM_FOCUS_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002439 max3aRegions.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002440 params.set(CameraParameters::KEY_FOCUS_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002441 "(0,0,0,0,0)");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002442 k.mParameters.focusingAreas.clear();
2443 k.mParameters.focusingAreas.add(Parameters::Area(0,0,0,0,0));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002444
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002445 camera_metadata_entry_t availableFocalLengths =
2446 staticInfo(ANDROID_LENS_AVAILABLE_FOCAL_LENGTHS);
2447 if (!availableFocalLengths.count) return NO_INIT;
2448
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002449 float minFocalLength = availableFocalLengths.data.f[0];
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002450 params.setFloat(CameraParameters::KEY_FOCAL_LENGTH, minFocalLength);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002451
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002452 camera_metadata_entry_t sensorSize =
2453 staticInfo(ANDROID_SENSOR_PHYSICAL_SIZE, 2, 2);
2454 if (!sensorSize.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002455
2456 // The fields of view here assume infinity focus, maximum wide angle
2457 float horizFov = 180 / M_PI *
2458 2 * atanf(sensorSize.data.f[0] / (2 * minFocalLength));
2459 float vertFov = 180 / M_PI *
2460 2 * atanf(sensorSize.data.f[1] / (2 * minFocalLength));
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002461 params.setFloat(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, horizFov);
2462 params.setFloat(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, vertFov);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002463
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002464 k.mParameters.exposureCompensation = 0;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002465 params.set(CameraParameters::KEY_EXPOSURE_COMPENSATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002466 k.mParameters.exposureCompensation);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002467
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002468 camera_metadata_entry_t exposureCompensationRange =
2469 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE, 2, 2);
2470 if (!exposureCompensationRange.count) return NO_INIT;
2471
2472 params.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002473 exposureCompensationRange.data.i32[1]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002474 params.set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002475 exposureCompensationRange.data.i32[0]);
2476
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002477 camera_metadata_entry_t exposureCompensationStep =
2478 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_STEP, 1, 1);
2479 if (!exposureCompensationStep.count) return NO_INIT;
2480
2481 params.setFloat(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP,
Eino-Ville Talvalad6f8e082012-08-02 16:00:35 -07002482 (float)exposureCompensationStep.data.r[0].numerator /
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002483 exposureCompensationStep.data.r[0].denominator);
2484
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002485 k.mParameters.autoExposureLock = false;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002486 params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK,
2487 CameraParameters::FALSE);
2488 params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED,
2489 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002490
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002491 k.mParameters.autoWhiteBalanceLock = false;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002492 params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK,
2493 CameraParameters::FALSE);
2494 params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED,
2495 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002496
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002497 k.mParameters.meteringAreas.add(Parameters::Area(0, 0, 0, 0, 0));
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002498 params.set(CameraParameters::KEY_MAX_NUM_METERING_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002499 max3aRegions.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002500 params.set(CameraParameters::KEY_METERING_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002501 "(0,0,0,0,0)");
2502
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002503 k.mParameters.zoom = 0;
2504 params.set(CameraParameters::KEY_ZOOM, k.mParameters.zoom);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002505 params.set(CameraParameters::KEY_MAX_ZOOM, NUM_ZOOM_STEPS - 1);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002506
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002507 camera_metadata_entry_t maxDigitalZoom =
2508 staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM, 1, 1);
2509 if (!maxDigitalZoom.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002510
2511 {
2512 String8 zoomRatios;
2513 float zoom = 1.f;
2514 float zoomIncrement = (maxDigitalZoom.data.f[0] - zoom) /
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002515 (NUM_ZOOM_STEPS-1);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002516 bool addComma = false;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002517 for (size_t i=0; i < NUM_ZOOM_STEPS; i++) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002518 if (addComma) zoomRatios += ",";
2519 addComma = true;
2520 zoomRatios += String8::format("%d", static_cast<int>(zoom * 100));
2521 zoom += zoomIncrement;
2522 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002523 params.set(CameraParameters::KEY_ZOOM_RATIOS, zoomRatios);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002524 }
2525
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002526 params.set(CameraParameters::KEY_ZOOM_SUPPORTED,
2527 CameraParameters::TRUE);
2528 params.set(CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED,
2529 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002530
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002531 params.set(CameraParameters::KEY_FOCUS_DISTANCES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002532 "Infinity,Infinity,Infinity");
2533
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002534 camera_metadata_entry_t maxFacesDetected =
2535 staticInfo(ANDROID_STATS_MAX_FACE_COUNT, 1, 1);
2536 params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002537 maxFacesDetected.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002538 params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002539 0);
2540
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002541 params.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT,
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002542 CameraParameters::PIXEL_FORMAT_ANDROID_OPAQUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002543
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002544 params.set(CameraParameters::KEY_RECORDING_HINT,
2545 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002546
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002547 params.set(CameraParameters::KEY_VIDEO_SNAPSHOT_SUPPORTED,
2548 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002549
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002550 params.set(CameraParameters::KEY_VIDEO_STABILIZATION,
2551 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002552
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002553 camera_metadata_entry_t availableVideoStabilizationModes =
2554 staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
2555 if (!availableVideoStabilizationModes.count) return NO_INIT;
2556
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002557 if (availableVideoStabilizationModes.count > 1) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002558 params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
2559 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002560 } else {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002561 params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
2562 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002563 }
2564
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07002565 // Set up initial state for non-Camera.Parameters state variables
2566
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002567 k.mParameters.storeMetadataInBuffers = true;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07002568 k.mParameters.playShutterSound = true;
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002569
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002570 k.mParameters.paramsFlattened = params.flatten();
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002571
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002572 return OK;
2573}
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07002574
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002575status_t Camera2Client::updatePreviewStream(const Parameters &params) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002576 ATRACE_CALL();
2577 status_t res;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002578
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002579 if (mPreviewStreamId != NO_STREAM) {
2580 // Check if stream parameters have to change
2581 uint32_t currentWidth, currentHeight;
2582 res = mDevice->getStreamInfo(mPreviewStreamId,
2583 &currentWidth, &currentHeight, 0);
2584 if (res != OK) {
2585 ALOGE("%s: Camera %d: Error querying preview stream info: "
2586 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2587 return res;
2588 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002589 if (currentWidth != (uint32_t)params.previewWidth ||
2590 currentHeight != (uint32_t)params.previewHeight) {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -07002591 ALOGV("%s: Camera %d: Preview size switch: %d x %d -> %d x %d",
2592 __FUNCTION__, mCameraId, currentWidth, currentHeight,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002593 params.previewWidth, params.previewHeight);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002594 res = mDevice->waitUntilDrained();
2595 if (res != OK) {
2596 ALOGE("%s: Camera %d: Error waiting for preview to drain: "
2597 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2598 return res;
2599 }
2600 res = mDevice->deleteStream(mPreviewStreamId);
2601 if (res != OK) {
2602 ALOGE("%s: Camera %d: Unable to delete old output stream "
2603 "for preview: %s (%d)", __FUNCTION__, mCameraId,
2604 strerror(-res), res);
2605 return res;
2606 }
2607 mPreviewStreamId = NO_STREAM;
2608 }
2609 }
2610
2611 if (mPreviewStreamId == NO_STREAM) {
2612 res = mDevice->createStream(mPreviewWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002613 params.previewWidth, params.previewHeight,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002614 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0,
2615 &mPreviewStreamId);
2616 if (res != OK) {
2617 ALOGE("%s: Camera %d: Unable to create preview stream: %s (%d)",
2618 __FUNCTION__, mCameraId, strerror(-res), res);
2619 return res;
2620 }
2621 }
2622
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07002623 res = mDevice->setStreamTransform(mPreviewStreamId,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002624 params.previewTransform);
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07002625 if (res != OK) {
2626 ALOGE("%s: Camera %d: Unable to set preview stream transform: "
2627 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2628 return res;
2629 }
2630
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002631 return OK;
2632}
2633
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002634status_t Camera2Client::updatePreviewRequest(const Parameters &params) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07002635 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002636 status_t res;
2637 if (mPreviewRequest == NULL) {
2638 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
2639 &mPreviewRequest);
2640 if (res != OK) {
2641 ALOGE("%s: Camera %d: Unable to create default preview request: "
2642 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2643 return res;
2644 }
2645 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002646
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002647 res = updateRequestCommon(mPreviewRequest, params);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002648 if (res != OK) {
2649 ALOGE("%s: Camera %d: Unable to update common entries of preview "
2650 "request: %s (%d)", __FUNCTION__, mCameraId,
2651 strerror(-res), res);
2652 return res;
2653 }
2654
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002655 return OK;
2656}
2657
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002658status_t Camera2Client::updateCaptureStream(const Parameters &params) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002659 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002660 status_t res;
2661 // Find out buffer size for JPEG
2662 camera_metadata_entry_t maxJpegSize =
2663 staticInfo(ANDROID_JPEG_MAX_SIZE);
2664 if (maxJpegSize.count == 0) {
2665 ALOGE("%s: Camera %d: Can't find ANDROID_JPEG_MAX_SIZE!",
2666 __FUNCTION__, mCameraId);
2667 return INVALID_OPERATION;
2668 }
2669
2670 if (mCaptureConsumer == 0) {
2671 // Create CPU buffer queue endpoint
2672 mCaptureConsumer = new CpuConsumer(1);
2673 mCaptureConsumer->setFrameAvailableListener(new CaptureWaiter(this));
2674 mCaptureConsumer->setName(String8("Camera2Client::CaptureConsumer"));
2675 mCaptureWindow = new SurfaceTextureClient(
2676 mCaptureConsumer->getProducerInterface());
2677 // Create memory for API consumption
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002678 mCaptureHeap = new Camera2Heap(maxJpegSize.data.i32[0], 1,
2679 "Camera2Client::CaptureHeap");
2680 if (mCaptureHeap->mHeap->getSize() == 0) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002681 ALOGE("%s: Camera %d: Unable to allocate memory for capture",
2682 __FUNCTION__, mCameraId);
2683 return NO_MEMORY;
2684 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002685 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002686
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002687 if (mCaptureStreamId != NO_STREAM) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002688 // Check if stream parameters have to change
2689 uint32_t currentWidth, currentHeight;
2690 res = mDevice->getStreamInfo(mCaptureStreamId,
2691 &currentWidth, &currentHeight, 0);
2692 if (res != OK) {
2693 ALOGE("%s: Camera %d: Error querying capture output stream info: "
2694 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2695 return res;
2696 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002697 if (currentWidth != (uint32_t)params.pictureWidth ||
2698 currentHeight != (uint32_t)params.pictureHeight) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002699 res = mDevice->deleteStream(mCaptureStreamId);
2700 if (res != OK) {
2701 ALOGE("%s: Camera %d: Unable to delete old output stream "
2702 "for capture: %s (%d)", __FUNCTION__, mCameraId,
2703 strerror(-res), res);
2704 return res;
2705 }
2706 mCaptureStreamId = NO_STREAM;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002707 }
2708 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002709
2710 if (mCaptureStreamId == NO_STREAM) {
2711 // Create stream for HAL production
2712 res = mDevice->createStream(mCaptureWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002713 params.pictureWidth, params.pictureHeight,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002714 HAL_PIXEL_FORMAT_BLOB, maxJpegSize.data.i32[0],
2715 &mCaptureStreamId);
2716 if (res != OK) {
2717 ALOGE("%s: Camera %d: Can't create output stream for capture: "
2718 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2719 return res;
2720 }
2721
2722 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002723 return OK;
2724}
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002725
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002726status_t Camera2Client::updateCaptureRequest(const Parameters &params) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002727 ATRACE_CALL();
2728 status_t res;
2729 if (mCaptureRequest == NULL) {
2730 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_STILL_CAPTURE,
2731 &mCaptureRequest);
2732 if (res != OK) {
2733 ALOGE("%s: Camera %d: Unable to create default still image request:"
2734 " %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2735 return res;
2736 }
2737 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002738
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002739 res = updateRequestCommon(mCaptureRequest, params);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002740 if (res != OK) {
2741 ALOGE("%s: Camera %d: Unable to update common entries of capture "
2742 "request: %s (%d)", __FUNCTION__, mCameraId,
2743 strerror(-res), res);
2744 return res;
2745 }
2746
2747 res = updateEntry(mCaptureRequest,
2748 ANDROID_JPEG_THUMBNAIL_SIZE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002749 params.jpegThumbSize, 2);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002750 if (res != OK) return res;
2751 res = updateEntry(mCaptureRequest,
2752 ANDROID_JPEG_THUMBNAIL_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002753 &params.jpegThumbQuality, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002754 if (res != OK) return res;
2755 res = updateEntry(mCaptureRequest,
2756 ANDROID_JPEG_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002757 &params.jpegQuality, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002758 if (res != OK) return res;
2759 res = updateEntry(mCaptureRequest,
2760 ANDROID_JPEG_ORIENTATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002761 &params.jpegRotation, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002762 if (res != OK) return res;
2763
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002764 if (params.gpsEnabled) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002765 res = updateEntry(mCaptureRequest,
2766 ANDROID_JPEG_GPS_COORDINATES,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002767 params.gpsCoordinates, 3);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002768 if (res != OK) return res;
2769 res = updateEntry(mCaptureRequest,
2770 ANDROID_JPEG_GPS_TIMESTAMP,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002771 &params.gpsTimestamp, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002772 if (res != OK) return res;
2773 res = updateEntry(mCaptureRequest,
2774 ANDROID_JPEG_GPS_PROCESSING_METHOD,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002775 params.gpsProcessingMethod.string(),
2776 params.gpsProcessingMethod.size());
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002777 if (res != OK) return res;
2778 } else {
2779 res = deleteEntry(mCaptureRequest,
2780 ANDROID_JPEG_GPS_COORDINATES);
2781 if (res != OK) return res;
2782 res = deleteEntry(mCaptureRequest,
2783 ANDROID_JPEG_GPS_TIMESTAMP);
2784 if (res != OK) return res;
2785 res = deleteEntry(mCaptureRequest,
2786 ANDROID_JPEG_GPS_PROCESSING_METHOD);
2787 if (res != OK) return res;
2788 }
2789
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002790 return OK;
2791}
2792
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002793status_t Camera2Client::updateRecordingRequest(const Parameters &params) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002794 ATRACE_CALL();
2795 status_t res;
2796 if (mRecordingRequest == NULL) {
2797 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_VIDEO_RECORD,
2798 &mRecordingRequest);
2799 if (res != OK) {
2800 ALOGE("%s: Camera %d: Unable to create default recording request:"
2801 " %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2802 return res;
2803 }
2804 }
2805
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002806 res = updateRequestCommon(mRecordingRequest, params);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002807 if (res != OK) {
2808 ALOGE("%s: Camera %d: Unable to update common entries of recording "
2809 "request: %s (%d)", __FUNCTION__, mCameraId,
2810 strerror(-res), res);
2811 return res;
2812 }
2813
2814 return OK;
2815}
2816
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002817status_t Camera2Client::updateRecordingStream(const Parameters &params) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002818 status_t res;
2819
2820 if (mRecordingConsumer == 0) {
2821 // Create CPU buffer queue endpoint
James Dong983cf232012-08-01 16:39:55 -07002822 mRecordingConsumer = new MediaConsumer(mRecordingHeapCount);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002823 mRecordingConsumer->setFrameAvailableListener(new RecordingWaiter(this));
2824 mRecordingConsumer->setName(String8("Camera2Client::RecordingConsumer"));
2825 mRecordingWindow = new SurfaceTextureClient(
2826 mRecordingConsumer->getProducerInterface());
2827 // Allocate memory later, since we don't know buffer size until receipt
2828 }
2829
2830 if (mRecordingStreamId != NO_STREAM) {
2831 // Check if stream parameters have to change
2832 uint32_t currentWidth, currentHeight;
2833 res = mDevice->getStreamInfo(mRecordingStreamId,
2834 &currentWidth, &currentHeight, 0);
2835 if (res != OK) {
2836 ALOGE("%s: Camera %d: Error querying recording output stream info: "
2837 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2838 return res;
2839 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002840 if (currentWidth != (uint32_t)params.videoWidth ||
2841 currentHeight != (uint32_t)params.videoHeight) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002842 // TODO: Should wait to be sure previous recording has finished
2843 res = mDevice->deleteStream(mRecordingStreamId);
2844 if (res != OK) {
2845 ALOGE("%s: Camera %d: Unable to delete old output stream "
2846 "for recording: %s (%d)", __FUNCTION__, mCameraId,
2847 strerror(-res), res);
2848 return res;
2849 }
2850 mRecordingStreamId = NO_STREAM;
2851 }
2852 }
2853
2854 if (mRecordingStreamId == NO_STREAM) {
2855 res = mDevice->createStream(mRecordingWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002856 params.videoWidth, params.videoHeight,
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002857 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0, &mRecordingStreamId);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002858 if (res != OK) {
2859 ALOGE("%s: Camera %d: Can't create output stream for recording: "
2860 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2861 return res;
2862 }
2863 }
2864
2865 return OK;
2866}
2867
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002868status_t Camera2Client::updateRequestCommon(camera_metadata_t *request,
2869 const Parameters &params) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002870 ATRACE_CALL();
2871 status_t res;
2872 res = updateEntry(request,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002873 ANDROID_CONTROL_AE_TARGET_FPS_RANGE, params.previewFpsRange, 2);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002874 if (res != OK) return res;
2875
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002876 uint8_t wbMode = params.autoWhiteBalanceLock ?
2877 ANDROID_CONTROL_AWB_LOCKED : params.wbMode;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002878 res = updateEntry(request,
2879 ANDROID_CONTROL_AWB_MODE, &wbMode, 1);
2880 if (res != OK) return res;
2881 res = updateEntry(request,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002882 ANDROID_CONTROL_EFFECT_MODE, &params.effectMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002883 if (res != OK) return res;
2884 res = updateEntry(request,
2885 ANDROID_CONTROL_AE_ANTIBANDING_MODE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002886 &params.antibandingMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002887 if (res != OK) return res;
2888
2889 uint8_t controlMode =
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002890 (params.sceneMode == ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED) ?
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002891 ANDROID_CONTROL_AUTO : ANDROID_CONTROL_USE_SCENE_MODE;
2892 res = updateEntry(request,
2893 ANDROID_CONTROL_MODE, &controlMode, 1);
2894 if (res != OK) return res;
2895 if (controlMode == ANDROID_CONTROL_USE_SCENE_MODE) {
2896 res = updateEntry(request,
2897 ANDROID_CONTROL_SCENE_MODE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002898 &params.sceneMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002899 if (res != OK) return res;
2900 }
2901
2902 uint8_t flashMode = ANDROID_FLASH_OFF;
2903 uint8_t aeMode;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002904 switch (params.flashMode) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002905 case Parameters::FLASH_MODE_OFF:
2906 aeMode = ANDROID_CONTROL_AE_ON; break;
2907 case Parameters::FLASH_MODE_AUTO:
2908 aeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH; break;
2909 case Parameters::FLASH_MODE_ON:
2910 aeMode = ANDROID_CONTROL_AE_ON_ALWAYS_FLASH; break;
2911 case Parameters::FLASH_MODE_TORCH:
2912 aeMode = ANDROID_CONTROL_AE_ON;
2913 flashMode = ANDROID_FLASH_TORCH;
2914 break;
2915 case Parameters::FLASH_MODE_RED_EYE:
2916 aeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE; break;
2917 default:
2918 ALOGE("%s: Camera %d: Unknown flash mode %d", __FUNCTION__,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002919 mCameraId, params.flashMode);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002920 return BAD_VALUE;
2921 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002922 if (params.autoExposureLock) aeMode = ANDROID_CONTROL_AE_LOCKED;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002923
2924 res = updateEntry(request,
2925 ANDROID_FLASH_MODE, &flashMode, 1);
2926 if (res != OK) return res;
2927 res = updateEntry(request,
2928 ANDROID_CONTROL_AE_MODE, &aeMode, 1);
2929 if (res != OK) return res;
2930
2931 float focusDistance = 0; // infinity focus in diopters
2932 uint8_t focusMode;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002933 switch (params.focusMode) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002934 case Parameters::FOCUS_MODE_AUTO:
2935 case Parameters::FOCUS_MODE_MACRO:
2936 case Parameters::FOCUS_MODE_CONTINUOUS_VIDEO:
2937 case Parameters::FOCUS_MODE_CONTINUOUS_PICTURE:
2938 case Parameters::FOCUS_MODE_EDOF:
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002939 focusMode = params.focusMode;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002940 break;
2941 case Parameters::FOCUS_MODE_INFINITY:
2942 case Parameters::FOCUS_MODE_FIXED:
2943 focusMode = ANDROID_CONTROL_AF_OFF;
2944 break;
2945 default:
2946 ALOGE("%s: Camera %d: Unknown focus mode %d", __FUNCTION__,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002947 mCameraId, params.focusMode);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002948 return BAD_VALUE;
2949 }
2950 res = updateEntry(request,
2951 ANDROID_LENS_FOCUS_DISTANCE, &focusDistance, 1);
2952 if (res != OK) return res;
2953 res = updateEntry(request,
2954 ANDROID_CONTROL_AF_MODE, &focusMode, 1);
2955 if (res != OK) return res;
2956
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002957 size_t focusingAreasSize = params.focusingAreas.size() * 5;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002958 int32_t *focusingAreas = new int32_t[focusingAreasSize];
2959 for (size_t i = 0; i < focusingAreasSize; i += 5) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002960 focusingAreas[i + 0] = params.focusingAreas[i].left;
2961 focusingAreas[i + 1] = params.focusingAreas[i].top;
2962 focusingAreas[i + 2] = params.focusingAreas[i].right;
2963 focusingAreas[i + 3] = params.focusingAreas[i].bottom;
2964 focusingAreas[i + 4] = params.focusingAreas[i].weight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002965 }
2966 res = updateEntry(request,
2967 ANDROID_CONTROL_AF_REGIONS, focusingAreas,focusingAreasSize);
2968 if (res != OK) return res;
2969 delete[] focusingAreas;
2970
2971 res = updateEntry(request,
2972 ANDROID_CONTROL_AE_EXP_COMPENSATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002973 &params.exposureCompensation, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002974 if (res != OK) return res;
2975
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002976 size_t meteringAreasSize = params.meteringAreas.size() * 5;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002977 int32_t *meteringAreas = new int32_t[meteringAreasSize];
2978 for (size_t i = 0; i < meteringAreasSize; i += 5) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002979 meteringAreas[i + 0] = params.meteringAreas[i].left;
2980 meteringAreas[i + 1] = params.meteringAreas[i].top;
2981 meteringAreas[i + 2] = params.meteringAreas[i].right;
2982 meteringAreas[i + 3] = params.meteringAreas[i].bottom;
2983 meteringAreas[i + 4] = params.meteringAreas[i].weight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002984 }
2985 res = updateEntry(request,
2986 ANDROID_CONTROL_AE_REGIONS, meteringAreas, meteringAreasSize);
2987 if (res != OK) return res;
2988
2989 res = updateEntry(request,
2990 ANDROID_CONTROL_AWB_REGIONS, meteringAreas, meteringAreasSize);
2991 if (res != OK) return res;
2992 delete[] meteringAreas;
2993
2994 // Need to convert zoom index into a crop rectangle. The rectangle is
2995 // chosen to maximize its area on the sensor
2996
2997 camera_metadata_entry_t maxDigitalZoom =
2998 staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM);
2999 float zoomIncrement = (maxDigitalZoom.data.f[0] - 1) /
3000 (NUM_ZOOM_STEPS-1);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003001 float zoomRatio = 1 + zoomIncrement * params.zoom;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003002
3003 camera_metadata_entry_t activePixelArraySize =
3004 staticInfo(ANDROID_SENSOR_ACTIVE_ARRAY_SIZE, 2, 2);
3005 int32_t arrayWidth = activePixelArraySize.data.i32[0];
3006 int32_t arrayHeight = activePixelArraySize.data.i32[1];
3007 float zoomLeft, zoomTop, zoomWidth, zoomHeight;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003008 if (params.previewWidth >= params.previewHeight) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003009 zoomWidth = arrayWidth / zoomRatio;
3010 zoomHeight = zoomWidth *
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003011 params.previewHeight / params.previewWidth;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003012 } else {
3013 zoomHeight = arrayHeight / zoomRatio;
3014 zoomWidth = zoomHeight *
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003015 params.previewWidth / params.previewHeight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003016 }
3017 zoomLeft = (arrayWidth - zoomWidth) / 2;
3018 zoomTop = (arrayHeight - zoomHeight) / 2;
3019
3020 int32_t cropRegion[3] = { zoomLeft, zoomTop, zoomWidth };
3021 res = updateEntry(request,
3022 ANDROID_SCALER_CROP_REGION, cropRegion, 3);
3023 if (res != OK) return res;
3024
3025 // TODO: Decide how to map recordingHint, or whether just to ignore it
3026
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003027 uint8_t vstabMode = params.videoStabilization ?
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003028 ANDROID_CONTROL_VIDEO_STABILIZATION_ON :
3029 ANDROID_CONTROL_VIDEO_STABILIZATION_OFF;
3030 res = updateEntry(request,
3031 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
3032 &vstabMode, 1);
3033 if (res != OK) return res;
3034
3035 return OK;
3036}
3037
3038status_t Camera2Client::updateEntry(camera_metadata_t *buffer,
3039 uint32_t tag, const void *data, size_t data_count) {
3040 camera_metadata_entry_t entry;
3041 status_t res;
3042 res = find_camera_metadata_entry(buffer, tag, &entry);
3043 if (res == NAME_NOT_FOUND) {
3044 res = add_camera_metadata_entry(buffer,
3045 tag, data, data_count);
3046 } else if (res == OK) {
3047 res = update_camera_metadata_entry(buffer,
3048 entry.index, data, data_count, NULL);
3049 }
3050
3051 if (res != OK) {
3052 ALOGE("%s: Unable to update metadata entry %s.%s (%x): %s (%d)",
3053 __FUNCTION__, get_camera_metadata_section_name(tag),
3054 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
3055 }
3056 return res;
3057}
3058
3059status_t Camera2Client::deleteEntry(camera_metadata_t *buffer, uint32_t tag) {
3060 camera_metadata_entry_t entry;
3061 status_t res;
3062 res = find_camera_metadata_entry(buffer, tag, &entry);
3063 if (res == NAME_NOT_FOUND) {
3064 return OK;
3065 } else if (res != OK) {
3066 ALOGE("%s: Error looking for entry %s.%s (%x): %s %d",
3067 __FUNCTION__,
3068 get_camera_metadata_section_name(tag),
3069 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
3070 return res;
3071 }
3072 res = delete_camera_metadata_entry(buffer, entry.index);
3073 if (res != OK) {
3074 ALOGE("%s: Error deleting entry %s.%s (%x): %s %d",
3075 __FUNCTION__,
3076 get_camera_metadata_section_name(tag),
3077 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
3078 }
3079 return res;
3080}
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003081
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07003082int Camera2Client::formatStringToEnum(const char *format) {
3083 return
3084 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422SP) ?
3085 HAL_PIXEL_FORMAT_YCbCr_422_SP : // NV16
3086 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420SP) ?
3087 HAL_PIXEL_FORMAT_YCrCb_420_SP : // NV21
3088 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422I) ?
3089 HAL_PIXEL_FORMAT_YCbCr_422_I : // YUY2
3090 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420P) ?
3091 HAL_PIXEL_FORMAT_YV12 : // YV12
3092 !strcmp(format, CameraParameters::PIXEL_FORMAT_RGB565) ?
3093 HAL_PIXEL_FORMAT_RGB_565 : // RGB565
3094 !strcmp(format, CameraParameters::PIXEL_FORMAT_RGBA8888) ?
3095 HAL_PIXEL_FORMAT_RGBA_8888 : // RGB8888
3096 !strcmp(format, CameraParameters::PIXEL_FORMAT_BAYER_RGGB) ?
3097 HAL_PIXEL_FORMAT_RAW_SENSOR : // Raw sensor data
3098 -1;
3099}
3100
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003101const char* Camera2Client::formatEnumToString(int format) {
3102 const char *fmt;
3103 switch(format) {
3104 case HAL_PIXEL_FORMAT_YCbCr_422_SP: // NV16
3105 fmt = CameraParameters::PIXEL_FORMAT_YUV422SP;
3106 break;
3107 case HAL_PIXEL_FORMAT_YCrCb_420_SP: // NV21
3108 fmt = CameraParameters::PIXEL_FORMAT_YUV420SP;
3109 break;
3110 case HAL_PIXEL_FORMAT_YCbCr_422_I: // YUY2
3111 fmt = CameraParameters::PIXEL_FORMAT_YUV422I;
3112 break;
3113 case HAL_PIXEL_FORMAT_YV12: // YV12
3114 fmt = CameraParameters::PIXEL_FORMAT_YUV420P;
3115 break;
3116 case HAL_PIXEL_FORMAT_RGB_565: // RGB565
3117 fmt = CameraParameters::PIXEL_FORMAT_RGB565;
3118 break;
3119 case HAL_PIXEL_FORMAT_RGBA_8888: // RGBA8888
3120 fmt = CameraParameters::PIXEL_FORMAT_RGBA8888;
3121 break;
3122 case HAL_PIXEL_FORMAT_RAW_SENSOR:
3123 ALOGW("Raw sensor preview format requested.");
3124 fmt = CameraParameters::PIXEL_FORMAT_BAYER_RGGB;
3125 break;
3126 default:
3127 ALOGE("%s: Unknown preview format: %x",
3128 __FUNCTION__, format);
3129 fmt = NULL;
3130 break;
3131 }
3132 return fmt;
3133}
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07003134
3135int Camera2Client::wbModeStringToEnum(const char *wbMode) {
3136 return
3137 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_AUTO) ?
3138 ANDROID_CONTROL_AWB_AUTO :
3139 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_INCANDESCENT) ?
3140 ANDROID_CONTROL_AWB_INCANDESCENT :
3141 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_FLUORESCENT) ?
3142 ANDROID_CONTROL_AWB_FLUORESCENT :
3143 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT) ?
3144 ANDROID_CONTROL_AWB_WARM_FLUORESCENT :
3145 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_DAYLIGHT) ?
3146 ANDROID_CONTROL_AWB_DAYLIGHT :
3147 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT) ?
3148 ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT :
3149 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_TWILIGHT) ?
3150 ANDROID_CONTROL_AWB_TWILIGHT :
3151 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_SHADE) ?
3152 ANDROID_CONTROL_AWB_SHADE :
3153 -1;
3154}
3155
3156int Camera2Client::effectModeStringToEnum(const char *effectMode) {
3157 return
3158 !strcmp(effectMode, CameraParameters::EFFECT_NONE) ?
3159 ANDROID_CONTROL_EFFECT_OFF :
3160 !strcmp(effectMode, CameraParameters::EFFECT_MONO) ?
3161 ANDROID_CONTROL_EFFECT_MONO :
3162 !strcmp(effectMode, CameraParameters::EFFECT_NEGATIVE) ?
3163 ANDROID_CONTROL_EFFECT_NEGATIVE :
3164 !strcmp(effectMode, CameraParameters::EFFECT_SOLARIZE) ?
3165 ANDROID_CONTROL_EFFECT_SOLARIZE :
3166 !strcmp(effectMode, CameraParameters::EFFECT_SEPIA) ?
3167 ANDROID_CONTROL_EFFECT_SEPIA :
3168 !strcmp(effectMode, CameraParameters::EFFECT_POSTERIZE) ?
3169 ANDROID_CONTROL_EFFECT_POSTERIZE :
3170 !strcmp(effectMode, CameraParameters::EFFECT_WHITEBOARD) ?
3171 ANDROID_CONTROL_EFFECT_WHITEBOARD :
3172 !strcmp(effectMode, CameraParameters::EFFECT_BLACKBOARD) ?
3173 ANDROID_CONTROL_EFFECT_BLACKBOARD :
3174 !strcmp(effectMode, CameraParameters::EFFECT_AQUA) ?
3175 ANDROID_CONTROL_EFFECT_AQUA :
3176 -1;
3177}
3178
3179int Camera2Client::abModeStringToEnum(const char *abMode) {
3180 return
3181 !strcmp(abMode, CameraParameters::ANTIBANDING_AUTO) ?
3182 ANDROID_CONTROL_AE_ANTIBANDING_AUTO :
3183 !strcmp(abMode, CameraParameters::ANTIBANDING_OFF) ?
3184 ANDROID_CONTROL_AE_ANTIBANDING_OFF :
3185 !strcmp(abMode, CameraParameters::ANTIBANDING_50HZ) ?
3186 ANDROID_CONTROL_AE_ANTIBANDING_50HZ :
3187 !strcmp(abMode, CameraParameters::ANTIBANDING_60HZ) ?
3188 ANDROID_CONTROL_AE_ANTIBANDING_60HZ :
3189 -1;
3190}
3191
3192int Camera2Client::sceneModeStringToEnum(const char *sceneMode) {
3193 return
3194 !strcmp(sceneMode, CameraParameters::SCENE_MODE_AUTO) ?
3195 ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED :
3196 !strcmp(sceneMode, CameraParameters::SCENE_MODE_ACTION) ?
3197 ANDROID_CONTROL_SCENE_MODE_ACTION :
3198 !strcmp(sceneMode, CameraParameters::SCENE_MODE_PORTRAIT) ?
3199 ANDROID_CONTROL_SCENE_MODE_PORTRAIT :
3200 !strcmp(sceneMode, CameraParameters::SCENE_MODE_LANDSCAPE) ?
3201 ANDROID_CONTROL_SCENE_MODE_LANDSCAPE :
3202 !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT) ?
3203 ANDROID_CONTROL_SCENE_MODE_NIGHT :
3204 !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT_PORTRAIT) ?
3205 ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT :
3206 !strcmp(sceneMode, CameraParameters::SCENE_MODE_THEATRE) ?
3207 ANDROID_CONTROL_SCENE_MODE_THEATRE :
3208 !strcmp(sceneMode, CameraParameters::SCENE_MODE_BEACH) ?
3209 ANDROID_CONTROL_SCENE_MODE_BEACH :
3210 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SNOW) ?
3211 ANDROID_CONTROL_SCENE_MODE_SNOW :
3212 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SUNSET) ?
3213 ANDROID_CONTROL_SCENE_MODE_SUNSET :
3214 !strcmp(sceneMode, CameraParameters::SCENE_MODE_STEADYPHOTO) ?
3215 ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO :
3216 !strcmp(sceneMode, CameraParameters::SCENE_MODE_FIREWORKS) ?
3217 ANDROID_CONTROL_SCENE_MODE_FIREWORKS :
3218 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SPORTS) ?
3219 ANDROID_CONTROL_SCENE_MODE_SPORTS :
3220 !strcmp(sceneMode, CameraParameters::SCENE_MODE_PARTY) ?
3221 ANDROID_CONTROL_SCENE_MODE_PARTY :
3222 !strcmp(sceneMode, CameraParameters::SCENE_MODE_CANDLELIGHT) ?
3223 ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT :
3224 !strcmp(sceneMode, CameraParameters::SCENE_MODE_BARCODE) ?
3225 ANDROID_CONTROL_SCENE_MODE_BARCODE:
3226 -1;
3227}
3228
3229Camera2Client::Parameters::flashMode_t Camera2Client::flashModeStringToEnum(
3230 const char *flashMode) {
3231 return
3232 !strcmp(flashMode, CameraParameters::FLASH_MODE_OFF) ?
3233 Parameters::FLASH_MODE_OFF :
3234 !strcmp(flashMode, CameraParameters::FLASH_MODE_AUTO) ?
3235 Parameters::FLASH_MODE_AUTO :
3236 !strcmp(flashMode, CameraParameters::FLASH_MODE_ON) ?
3237 Parameters::FLASH_MODE_ON :
3238 !strcmp(flashMode, CameraParameters::FLASH_MODE_RED_EYE) ?
3239 Parameters::FLASH_MODE_RED_EYE :
3240 !strcmp(flashMode, CameraParameters::FLASH_MODE_TORCH) ?
3241 Parameters::FLASH_MODE_TORCH :
3242 Parameters::FLASH_MODE_INVALID;
3243}
3244
3245Camera2Client::Parameters::focusMode_t Camera2Client::focusModeStringToEnum(
3246 const char *focusMode) {
3247 return
3248 !strcmp(focusMode, CameraParameters::FOCUS_MODE_AUTO) ?
3249 Parameters::FOCUS_MODE_AUTO :
3250 !strcmp(focusMode, CameraParameters::FOCUS_MODE_INFINITY) ?
3251 Parameters::FOCUS_MODE_INFINITY :
3252 !strcmp(focusMode, CameraParameters::FOCUS_MODE_MACRO) ?
3253 Parameters::FOCUS_MODE_MACRO :
3254 !strcmp(focusMode, CameraParameters::FOCUS_MODE_FIXED) ?
3255 Parameters::FOCUS_MODE_FIXED :
3256 !strcmp(focusMode, CameraParameters::FOCUS_MODE_EDOF) ?
3257 Parameters::FOCUS_MODE_EDOF :
3258 !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO) ?
3259 Parameters::FOCUS_MODE_CONTINUOUS_VIDEO :
3260 !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE) ?
3261 Parameters::FOCUS_MODE_CONTINUOUS_PICTURE :
3262 Parameters::FOCUS_MODE_INVALID;
3263}
3264
3265status_t Camera2Client::parseAreas(const char *areasCStr,
3266 Vector<Parameters::Area> *areas) {
3267 static const size_t NUM_FIELDS = 5;
3268 areas->clear();
3269 if (areasCStr == NULL) {
3270 // If no key exists, use default (0,0,0,0,0)
3271 areas->push();
3272 return OK;
3273 }
3274 String8 areasStr(areasCStr);
3275 ssize_t areaStart = areasStr.find("(", 0) + 1;
3276 while (areaStart != 0) {
3277 const char* area = areasStr.string() + areaStart;
3278 char *numEnd;
3279 int vals[NUM_FIELDS];
3280 for (size_t i = 0; i < NUM_FIELDS; i++) {
3281 errno = 0;
3282 vals[i] = strtol(area, &numEnd, 10);
3283 if (errno || numEnd == area) return BAD_VALUE;
3284 area = numEnd + 1;
3285 }
3286 areas->push(Parameters::Area(
3287 vals[0], vals[1], vals[2], vals[3], vals[4]) );
3288 areaStart = areasStr.find("(", areaStart) + 1;
3289 }
3290 return OK;
3291}
3292
3293status_t Camera2Client::validateAreas(const Vector<Parameters::Area> &areas,
3294 size_t maxRegions) {
3295 // Definition of valid area can be found in
3296 // include/camera/CameraParameters.h
3297 if (areas.size() == 0) return BAD_VALUE;
3298 if (areas.size() == 1) {
3299 if (areas[0].left == 0 &&
3300 areas[0].top == 0 &&
3301 areas[0].right == 0 &&
3302 areas[0].bottom == 0 &&
3303 areas[0].weight == 0) {
3304 // Single (0,0,0,0,0) entry is always valid (== driver decides)
3305 return OK;
3306 }
3307 }
3308 if (areas.size() > maxRegions) {
3309 ALOGE("%s: Too many areas requested: %d",
3310 __FUNCTION__, areas.size());
3311 return BAD_VALUE;
3312 }
3313
3314 for (Vector<Parameters::Area>::const_iterator a = areas.begin();
3315 a != areas.end(); a++) {
3316 if (a->weight < 1 || a->weight > 1000) return BAD_VALUE;
3317 if (a->left < -1000 || a->left > 1000) return BAD_VALUE;
3318 if (a->top < -1000 || a->top > 1000) return BAD_VALUE;
3319 if (a->right < -1000 || a->right > 1000) return BAD_VALUE;
3320 if (a->bottom < -1000 || a->bottom > 1000) return BAD_VALUE;
3321 if (a->left >= a->right) return BAD_VALUE;
3322 if (a->top >= a->bottom) return BAD_VALUE;
3323 }
3324 return OK;
3325}
3326
3327bool Camera2Client::boolFromString(const char *boolStr) {
3328 return !boolStr ? false :
3329 !strcmp(boolStr, CameraParameters::TRUE) ? true :
3330 false;
3331}
3332
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07003333int Camera2Client::degToTransform(int degrees, bool mirror) {
3334 if (!mirror) {
3335 if (degrees == 0) return 0;
3336 else if (degrees == 90) return HAL_TRANSFORM_ROT_90;
3337 else if (degrees == 180) return HAL_TRANSFORM_ROT_180;
3338 else if (degrees == 270) return HAL_TRANSFORM_ROT_270;
3339 } else { // Do mirror (horizontal flip)
3340 if (degrees == 0) { // FLIP_H and ROT_0
3341 return HAL_TRANSFORM_FLIP_H;
3342 } else if (degrees == 90) { // FLIP_H and ROT_90
3343 return HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90;
3344 } else if (degrees == 180) { // FLIP_H and ROT_180
3345 return HAL_TRANSFORM_FLIP_V;
3346 } else if (degrees == 270) { // FLIP_H and ROT_270
3347 return HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90;
3348 }
3349 }
3350 ALOGE("%s: Bad input: %d", __FUNCTION__, degrees);
3351 return -1;
3352}
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07003353
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07003354} // namespace android