blob: 9c2fbcbf9a0bc6478907d55fcdaad5c7b749edee [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
Eino-Ville Talvala174181e2012-08-03 13:53:39 -070091 res = mDevice->setNotifyCallback(this);
92
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070093 res = buildDefaultParameters();
94 if (res != OK) {
95 ALOGE("%s: Camera %d: unable to build defaults: %s (%d)",
96 __FUNCTION__, mCameraId, strerror(-res), res);
97 return NO_INIT;
98 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -070099
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700100 if (gLogLevel >= 1) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700101 LockedParameters::Key k(mParameters);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700102 ALOGD("%s: Default parameters converted from camera %d:", __FUNCTION__,
103 mCameraId);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700104 ALOGD("%s", k.mParameters.paramsFlattened.string());
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700105 }
106
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700107 mState = STOPPED;
108
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700109 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700110}
111
112Camera2Client::~Camera2Client() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700113 ATRACE_CALL();
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700114 ALOGV("%s: Camera %d: Shutting down", __FUNCTION__, mCameraId);
115
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700116 mDestructionStarted = true;
117
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700118 // Rewrite mClientPid to allow shutdown by CameraService
119 mClientPid = getCallingPid();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700120 disconnect();
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700121}
122
123status_t Camera2Client::dump(int fd, const Vector<String16>& args) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700124 String8 result;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700125 result.appendFormat("Client2[%d] (%p) PID: %d, dump:\n",
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700126 mCameraId,
127 getCameraClient()->asBinder().get(),
128 mClientPid);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700129 result.append(" State: ");
130#define CASE_APPEND_ENUM(x) case x: result.append(#x "\n"); break;
131
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700132 const Parameters& p = mParameters.unsafeUnlock();
133
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700134 result.append(getStateName(mState));
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700135
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700136 result.append("\n Current parameters:\n");
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700137 result.appendFormat(" Preview size: %d x %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700138 p.previewWidth, p.previewHeight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700139 result.appendFormat(" Preview FPS range: %d - %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700140 p.previewFpsRange[0], p.previewFpsRange[1]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700141 result.appendFormat(" Preview HAL pixel format: 0x%x\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700142 p.previewFormat);
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700143 result.appendFormat(" Preview transform: %x\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700144 p.previewTransform);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700145 result.appendFormat(" Picture size: %d x %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700146 p.pictureWidth, p.pictureHeight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700147 result.appendFormat(" Jpeg thumbnail size: %d x %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700148 p.jpegThumbSize[0], p.jpegThumbSize[1]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700149 result.appendFormat(" Jpeg quality: %d, thumbnail quality: %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700150 p.jpegQuality, p.jpegThumbQuality);
151 result.appendFormat(" Jpeg rotation: %d\n", p.jpegRotation);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700152 result.appendFormat(" GPS tags %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700153 p.gpsEnabled ? "enabled" : "disabled");
154 if (p.gpsEnabled) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700155 result.appendFormat(" GPS lat x long x alt: %f x %f x %f\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700156 p.gpsCoordinates[0], p.gpsCoordinates[1],
157 p.gpsCoordinates[2]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700158 result.appendFormat(" GPS timestamp: %lld\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700159 p.gpsTimestamp);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700160 result.appendFormat(" GPS processing method: %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700161 p.gpsProcessingMethod.string());
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700162 }
163
164 result.append(" White balance mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700165 switch (p.wbMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700166 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_AUTO)
167 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_INCANDESCENT)
168 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_FLUORESCENT)
169 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_WARM_FLUORESCENT)
170 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_DAYLIGHT)
171 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT)
172 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_TWILIGHT)
173 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_SHADE)
174 default: result.append("UNKNOWN\n");
175 }
176
177 result.append(" Effect mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700178 switch (p.effectMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700179 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_OFF)
180 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_MONO)
181 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_NEGATIVE)
182 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_SOLARIZE)
183 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_SEPIA)
184 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_POSTERIZE)
185 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_WHITEBOARD)
186 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_BLACKBOARD)
187 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_AQUA)
188 default: result.append("UNKNOWN\n");
189 }
190
191 result.append(" Antibanding mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700192 switch (p.antibandingMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700193 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_AUTO)
194 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_OFF)
195 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_50HZ)
196 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_60HZ)
197 default: result.append("UNKNOWN\n");
198 }
199
200 result.append(" Scene mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700201 switch (p.sceneMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700202 case ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED:
203 result.append("AUTO\n"); break;
204 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_ACTION)
205 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_PORTRAIT)
206 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_LANDSCAPE)
207 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_NIGHT)
208 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT)
209 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_THEATRE)
210 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_BEACH)
211 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SNOW)
212 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SUNSET)
213 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO)
214 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_FIREWORKS)
215 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SPORTS)
216 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_PARTY)
217 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT)
218 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_BARCODE)
219 default: result.append("UNKNOWN\n");
220 }
221
222 result.append(" Flash mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700223 switch (p.flashMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700224 CASE_APPEND_ENUM(Parameters::FLASH_MODE_OFF)
225 CASE_APPEND_ENUM(Parameters::FLASH_MODE_AUTO)
226 CASE_APPEND_ENUM(Parameters::FLASH_MODE_ON)
227 CASE_APPEND_ENUM(Parameters::FLASH_MODE_TORCH)
228 CASE_APPEND_ENUM(Parameters::FLASH_MODE_RED_EYE)
229 CASE_APPEND_ENUM(Parameters::FLASH_MODE_INVALID)
230 default: result.append("UNKNOWN\n");
231 }
232
233 result.append(" Focus mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700234 switch (p.focusMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700235 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_AUTO)
236 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_MACRO)
237 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_CONTINUOUS_VIDEO)
238 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_CONTINUOUS_PICTURE)
239 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_EDOF)
240 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_INFINITY)
241 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_FIXED)
242 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_INVALID)
243 default: result.append("UNKNOWN\n");
244 }
245
246 result.append(" Focusing areas:\n");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700247 for (size_t i = 0; i < p.focusingAreas.size(); i++) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700248 result.appendFormat(" [ (%d, %d, %d, %d), weight %d ]\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700249 p.focusingAreas[i].left,
250 p.focusingAreas[i].top,
251 p.focusingAreas[i].right,
252 p.focusingAreas[i].bottom,
253 p.focusingAreas[i].weight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700254 }
255
256 result.appendFormat(" Exposure compensation index: %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700257 p.exposureCompensation);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700258
259 result.appendFormat(" AE lock %s, AWB lock %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700260 p.autoExposureLock ? "enabled" : "disabled",
261 p.autoWhiteBalanceLock ? "enabled" : "disabled" );
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700262
263 result.appendFormat(" Metering areas:\n");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700264 for (size_t i = 0; i < p.meteringAreas.size(); i++) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700265 result.appendFormat(" [ (%d, %d, %d, %d), weight %d ]\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700266 p.meteringAreas[i].left,
267 p.meteringAreas[i].top,
268 p.meteringAreas[i].right,
269 p.meteringAreas[i].bottom,
270 p.meteringAreas[i].weight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700271 }
272
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700273 result.appendFormat(" Zoom index: %d\n", p.zoom);
274 result.appendFormat(" Video size: %d x %d\n", p.videoWidth,
275 p.videoHeight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700276
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700277 result.appendFormat(" Recording hint is %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700278 p.recordingHint ? "set" : "not set");
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700279
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700280 result.appendFormat(" Video stabilization is %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700281 p.videoStabilization ? "enabled" : "disabled");
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700282
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700283 result.append(" Current streams:\n");
284 result.appendFormat(" Preview stream ID: %d\n", mPreviewStreamId);
285 result.appendFormat(" Capture stream ID: %d\n", mCaptureStreamId);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700286 result.appendFormat(" Recording stream ID: %d\n", mRecordingStreamId);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700287
288 result.append(" Current requests:\n");
289 if (mPreviewRequest != NULL) {
290 result.append(" Preview request:\n");
291 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700292 dump_indented_camera_metadata(mPreviewRequest, fd, 2, 6);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700293 } else {
294 result.append(" Preview request: undefined\n");
295 write(fd, result.string(), result.size());
296 }
297
298 if (mCaptureRequest != NULL) {
299 result = " Capture request:\n";
300 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700301 dump_indented_camera_metadata(mCaptureRequest, fd, 2, 6);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700302 } else {
303 result = " Capture request: undefined\n";
304 write(fd, result.string(), result.size());
305 }
306
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700307 if (mRecordingRequest != NULL) {
308 result = " Recording request:\n";
309 write(fd, result.string(), result.size());
310 dump_indented_camera_metadata(mRecordingRequest, fd, 2, 6);
311 } else {
312 result = " Recording request: undefined\n";
313 write(fd, result.string(), result.size());
314 }
315
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700316 result = " Device dump:\n";
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700317 write(fd, result.string(), result.size());
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700318
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700319 status_t res = mDevice->dump(fd, args);
320 if (res != OK) {
321 result = String8::format(" Error dumping device: %s (%d)",
322 strerror(-res), res);
323 write(fd, result.string(), result.size());
324 }
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700325
326#undef CASE_APPEND_ENUM
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700327 return NO_ERROR;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700328}
329
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700330const char* Camera2Client::getStateName(State state) {
331#define CASE_ENUM_TO_CHAR(x) case x: return(#x); break;
332 switch(state) {
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700333 CASE_ENUM_TO_CHAR(DISCONNECTED)
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700334 CASE_ENUM_TO_CHAR(STOPPED)
335 CASE_ENUM_TO_CHAR(WAITING_FOR_PREVIEW_WINDOW)
336 CASE_ENUM_TO_CHAR(PREVIEW)
337 CASE_ENUM_TO_CHAR(RECORD)
338 CASE_ENUM_TO_CHAR(STILL_CAPTURE)
339 CASE_ENUM_TO_CHAR(VIDEO_SNAPSHOT)
340 default:
341 return "Unknown state!";
342 break;
343 }
344#undef CASE_ENUM_TO_CHAR
345}
346
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700347// ICamera interface
348
349void Camera2Client::disconnect() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700350 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700351 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700352 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700353 status_t res;
354 if ( (res = checkPid(__FUNCTION__) ) != OK) return;
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700355
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700356 if (mDevice == 0) return;
357
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700358 stopPreviewL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700359
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700360 mDevice->waitUntilDrained();
361
362 if (mPreviewStreamId != NO_STREAM) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700363 mDevice->deleteStream(mPreviewStreamId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700364 mPreviewStreamId = NO_STREAM;
365 }
366
367 if (mCaptureStreamId != NO_STREAM) {
368 mDevice->deleteStream(mCaptureStreamId);
369 mCaptureStreamId = NO_STREAM;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700370 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700371
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -0700372 if (mRecordingStreamId != NO_STREAM) {
373 mDevice->deleteStream(mRecordingStreamId);
374 mRecordingStreamId = NO_STREAM;
375 }
376
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700377 mDevice.clear();
378 mState = DISCONNECTED;
379
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700380 CameraService::Client::disconnect();
381}
382
383status_t Camera2Client::connect(const sp<ICameraClient>& client) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700384 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700385 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700386 Mutex::Autolock icl(mICameraLock);
387
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700388 if (mClientPid != 0 && getCallingPid() != mClientPid) {
389 ALOGE("%s: Camera %d: Connection attempt from pid %d; "
390 "current locked to pid %d", __FUNCTION__,
391 mCameraId, getCallingPid(), mClientPid);
392 return BAD_VALUE;
393 }
394
395 mClientPid = getCallingPid();
396 mCameraClient = client;
397
398 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700399}
400
401status_t Camera2Client::lock() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700402 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700403 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700404 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700405 ALOGV("%s: Camera %d: Lock call from pid %d; current client pid %d",
406 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700407
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700408 if (mClientPid == 0) {
409 mClientPid = getCallingPid();
410 return OK;
411 }
412
413 if (mClientPid != getCallingPid()) {
414 ALOGE("%s: Camera %d: Lock call from pid %d; currently locked to pid %d",
415 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
416 return EBUSY;
417 }
418
419 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700420}
421
422status_t Camera2Client::unlock() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700423 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700424 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700425 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700426 ALOGV("%s: Camera %d: Unlock call from pid %d; current client pid %d",
427 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700428
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700429 // TODO: Check for uninterruptable conditions
430
431 if (mClientPid == getCallingPid()) {
432 mClientPid = 0;
433 mCameraClient.clear();
434 return OK;
435 }
436
437 ALOGE("%s: Camera %d: Unlock call from pid %d; currently locked to pid %d",
438 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
439 return EBUSY;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700440}
441
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700442status_t Camera2Client::setPreviewDisplay(
443 const sp<Surface>& surface) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700444 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700445 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700446 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700447 status_t res;
448 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700449
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700450 sp<IBinder> binder;
451 sp<ANativeWindow> window;
452 if (surface != 0) {
453 binder = surface->asBinder();
454 window = surface;
455 }
456
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700457 return setPreviewWindowL(binder,window);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700458}
459
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700460status_t Camera2Client::setPreviewTexture(
461 const sp<ISurfaceTexture>& surfaceTexture) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700462 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700463 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700464 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700465 status_t res;
466 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700467
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700468 sp<IBinder> binder;
469 sp<ANativeWindow> window;
470 if (surfaceTexture != 0) {
471 binder = surfaceTexture->asBinder();
472 window = new SurfaceTextureClient(surfaceTexture);
473 }
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700474 return setPreviewWindowL(binder, window);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700475}
476
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700477status_t Camera2Client::setPreviewWindowL(const sp<IBinder>& binder,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700478 sp<ANativeWindow> window) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700479 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700480 status_t res;
481
482 if (binder == mPreviewSurface) {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700483 ALOGV("%s: Camera %d: New window is same as old window",
484 __FUNCTION__, mCameraId);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700485 return NO_ERROR;
486 }
487
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700488 switch (mState) {
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700489 case DISCONNECTED:
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700490 case RECORD:
491 case STILL_CAPTURE:
492 case VIDEO_SNAPSHOT:
493 ALOGE("%s: Camera %d: Cannot set preview display while in state %s",
494 __FUNCTION__, mCameraId, getStateName(mState));
495 return INVALID_OPERATION;
496 case STOPPED:
497 case WAITING_FOR_PREVIEW_WINDOW:
498 // OK
499 break;
500 case PREVIEW:
501 // Already running preview - need to stop and create a new stream
502 // TODO: Optimize this so that we don't wait for old stream to drain
503 // before spinning up new stream
504 mDevice->setStreamingRequest(NULL);
505 mState = WAITING_FOR_PREVIEW_WINDOW;
506 break;
507 }
508
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700509 if (mPreviewStreamId != NO_STREAM) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700510 res = mDevice->waitUntilDrained();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700511 if (res != OK) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700512 ALOGE("%s: Error waiting for preview to drain: %s (%d)",
513 __FUNCTION__, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700514 return res;
515 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700516 res = mDevice->deleteStream(mPreviewStreamId);
517 if (res != OK) {
518 ALOGE("%s: Unable to delete old preview stream: %s (%d)",
519 __FUNCTION__, strerror(-res), res);
520 return res;
521 }
522 mPreviewStreamId = NO_STREAM;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700523 }
524
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700525 mPreviewSurface = binder;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700526 mPreviewWindow = window;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700527
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700528 if (mState == WAITING_FOR_PREVIEW_WINDOW) {
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700529 return startPreviewL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700530 }
531
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700532 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700533}
534
535void Camera2Client::setPreviewCallbackFlag(int flag) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700536 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700537 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700538 status_t res;
539 if ( (res = checkPid(__FUNCTION__) ) != OK) return;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700540}
541
542status_t Camera2Client::startPreview() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700543 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700544 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700545 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700546 status_t res;
547 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700548 return startPreviewL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700549}
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700550
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700551status_t Camera2Client::startPreviewL() {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700552 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700553 status_t res;
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700554 if (mState >= PREVIEW) {
555 ALOGE("%s: Can't start preview in state %s",
556 __FUNCTION__, getStateName(mState));
557 return INVALID_OPERATION;
558 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700559
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700560 if (mPreviewWindow == 0) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700561 mState = WAITING_FOR_PREVIEW_WINDOW;
562 return OK;
563 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700564 mState = STOPPED;
565
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700566 LockedParameters::Key k(mParameters);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700567
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700568 res = updatePreviewStream(k.mParameters);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700569 if (res != OK) {
570 ALOGE("%s: Camera %d: Unable to update preview stream: %s (%d)",
571 __FUNCTION__, mCameraId, strerror(-res), res);
572 return res;
573 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700574
575 if (mPreviewRequest == NULL) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700576 res = updatePreviewRequest(k.mParameters);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700577 if (res != OK) {
578 ALOGE("%s: Camera %d: Unable to create preview request: %s (%d)",
579 __FUNCTION__, mCameraId, strerror(-res), res);
580 return res;
581 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700582 }
583
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700584 res = updateEntry(mPreviewRequest,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700585 ANDROID_REQUEST_OUTPUT_STREAMS,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700586 &mPreviewStreamId, 1);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700587 if (res != OK) {
588 ALOGE("%s: Camera %d: Unable to set up preview request: %s (%d)",
589 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700590 return res;
591 }
592 res = sort_camera_metadata(mPreviewRequest);
593 if (res != OK) {
594 ALOGE("%s: Camera %d: Error sorting preview request: %s (%d)",
595 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700596 return res;
597 }
598
599 res = mDevice->setStreamingRequest(mPreviewRequest);
600 if (res != OK) {
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700601 ALOGE("%s: Camera %d: Unable to set preview request to start preview: "
602 "%s (%d)",
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700603 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700604 return res;
605 }
606 mState = PREVIEW;
607
608 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700609}
610
611void Camera2Client::stopPreview() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700612 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700613 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700614 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700615 status_t res;
616 if ( (res = checkPid(__FUNCTION__) ) != OK) return;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700617 stopPreviewL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700618}
619
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700620void Camera2Client::stopPreviewL() {
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700621 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700622 switch (mState) {
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700623 case DISCONNECTED:
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700624 ALOGE("%s: Camera %d: Call before initialized",
625 __FUNCTION__, mCameraId);
626 break;
627 case STOPPED:
628 break;
629 case STILL_CAPTURE:
630 ALOGE("%s: Camera %d: Cannot stop preview during still capture.",
631 __FUNCTION__, mCameraId);
632 break;
633 case RECORD:
634 // TODO: Handle record stop here
635 case PREVIEW:
636 mDevice->setStreamingRequest(NULL);
Eino-Ville Talvala22671062012-07-20 18:30:37 -0700637 mDevice->waitUntilDrained();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700638 case WAITING_FOR_PREVIEW_WINDOW:
639 mState = STOPPED;
640 break;
641 default:
642 ALOGE("%s: Camera %d: Unknown state %d", __FUNCTION__, mCameraId,
643 mState);
644 }
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700645}
646
647bool Camera2Client::previewEnabled() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700648 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700649 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700650 status_t res;
651 if ( (res = checkPid(__FUNCTION__) ) != OK) return false;
652
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700653 return mState == PREVIEW;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700654}
655
656status_t Camera2Client::storeMetaDataInBuffers(bool enabled) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700657 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700658 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700659 status_t res;
660 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
661
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700662 switch (mState) {
663 case RECORD:
664 case VIDEO_SNAPSHOT:
665 ALOGE("%s: Camera %d: Can't be called in state %s",
666 __FUNCTION__, mCameraId, getStateName(mState));
667 return INVALID_OPERATION;
668 default:
669 // OK
670 break;
671 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700672 LockedParameters::Key k(mParameters);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700673
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700674 k.mParameters.storeMetadataInBuffers = enabled;
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700675
676 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700677}
678
679status_t Camera2Client::startRecording() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700680 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700681 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700682 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700683 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700684 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
685
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700686 switch (mState) {
687 case STOPPED:
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700688 res = startPreviewL();
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700689 if (res != OK) return res;
690 break;
691 case PREVIEW:
692 // Ready to go
693 break;
694 case RECORD:
695 case VIDEO_SNAPSHOT:
696 // OK to call this when recording is already on
697 return OK;
698 break;
699 default:
700 ALOGE("%s: Camera %d: Can't start recording in state %s",
701 __FUNCTION__, mCameraId, getStateName(mState));
702 return INVALID_OPERATION;
703 };
704
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700705 LockedParameters::Key k(mParameters);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700706
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700707 if (!k.mParameters.storeMetadataInBuffers) {
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700708 ALOGE("%s: Camera %d: Recording only supported in metadata mode, but "
709 "non-metadata recording mode requested!", __FUNCTION__,
710 mCameraId);
711 return INVALID_OPERATION;
712 }
713
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700714 res = updateRecordingStream(k.mParameters);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700715 if (res != OK) {
716 ALOGE("%s: Camera %d: Unable to update recording stream: %s (%d)",
717 __FUNCTION__, mCameraId, strerror(-res), res);
718 return res;
719 }
720
721 if (mRecordingRequest == NULL) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700722 res = updateRecordingRequest(k.mParameters);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700723 if (res != OK) {
724 ALOGE("%s: Camera %d: Unable to create recording request: %s (%d)",
725 __FUNCTION__, mCameraId, strerror(-res), res);
726 return res;
727 }
728 }
729
730 uint8_t outputStreams[2] = { mPreviewStreamId, mRecordingStreamId };
731 res = updateEntry(mRecordingRequest,
732 ANDROID_REQUEST_OUTPUT_STREAMS,
733 outputStreams, 2);
734 if (res != OK) {
735 ALOGE("%s: Camera %d: Unable to set up recording request: %s (%d)",
736 __FUNCTION__, mCameraId, strerror(-res), res);
737 return res;
738 }
739 res = sort_camera_metadata(mRecordingRequest);
740 if (res != OK) {
741 ALOGE("%s: Camera %d: Error sorting recording request: %s (%d)",
742 __FUNCTION__, mCameraId, strerror(-res), res);
743 return res;
744 }
745
746 res = mDevice->setStreamingRequest(mRecordingRequest);
747 if (res != OK) {
748 ALOGE("%s: Camera %d: Unable to set recording request to start "
749 "recording: %s (%d)", __FUNCTION__, mCameraId,
750 strerror(-res), res);
751 return res;
752 }
753 mState = RECORD;
754
755 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700756}
757
758void Camera2Client::stopRecording() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700759 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700760 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700761 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700762 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700763 if ( (res = checkPid(__FUNCTION__) ) != OK) return;
764
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700765 switch (mState) {
766 case RECORD:
767 // OK to stop
768 break;
769 case STOPPED:
770 case PREVIEW:
771 case STILL_CAPTURE:
772 case VIDEO_SNAPSHOT:
773 default:
774 ALOGE("%s: Camera %d: Can't stop recording in state %s",
775 __FUNCTION__, mCameraId, getStateName(mState));
776 return;
777 };
778
779 // Back to preview. Since record can only be reached through preview,
780 // all preview stream setup should be up to date.
781 res = mDevice->setStreamingRequest(mPreviewRequest);
782 if (res != OK) {
783 ALOGE("%s: Camera %d: Unable to switch back to preview request: "
784 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
785 return;
786 }
787
788 // TODO: Should recording heap be freed? Can't do it yet since requests
789 // could still be in flight.
790
791 mState = PREVIEW;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700792}
793
794bool Camera2Client::recordingEnabled() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700795 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700796 Mutex::Autolock icl(mICameraLock);
James Dong8da4cd72012-08-04 19:58:07 -0700797
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700798 if ( checkPid(__FUNCTION__) != OK) return false;
799
James Dong8da4cd72012-08-04 19:58:07 -0700800 return recordingEnabledL();
801}
802
803bool Camera2Client::recordingEnabledL() {
804 ATRACE_CALL();
805
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700806 return (mState == RECORD || mState == VIDEO_SNAPSHOT);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700807}
808
809void Camera2Client::releaseRecordingFrame(const sp<IMemory>& mem) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700810 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700811 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700812 status_t res;
813 if ( checkPid(__FUNCTION__) != OK) return;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700814 // Make sure this is for the current heap
815 ssize_t offset;
816 size_t size;
817 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
818 if (heap->getHeapID() != mRecordingHeap->mHeap->getHeapID()) {
819 ALOGW("%s: Camera %d: Mismatched heap ID, ignoring release "
820 "(got %x, expected %x)", __FUNCTION__, mCameraId,
821 heap->getHeapID(), mRecordingHeap->mHeap->getHeapID());
822 return;
823 }
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700824 uint8_t *data = (uint8_t*)heap->getBase() + offset;
825 uint32_t type = *(uint32_t*)data;
826 if (type != kMetadataBufferTypeGrallocSource) {
827 ALOGE("%s: Camera %d: Recording frame type invalid (got %x, expected %x)",
828 __FUNCTION__, mCameraId, type, kMetadataBufferTypeGrallocSource);
829 return;
830 }
831 buffer_handle_t imgBuffer = *(buffer_handle_t*)(data + 4);
832 ALOGV("%s: Camera %d: Freeing buffer_handle_t %p", __FUNCTION__, mCameraId,
Eino-Ville Talvala803cbf62012-07-25 15:23:36 -0700833 imgBuffer);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700834 res = mRecordingConsumer->freeBuffer(imgBuffer);
835 if (res != OK) {
836 ALOGE("%s: Camera %d: Unable to free recording frame (buffer_handle_t: %p):"
837 "%s (%d)",
838 __FUNCTION__, mCameraId, imgBuffer, strerror(-res), res);
839 return;
840 }
841
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700842 mRecordingHeapFree++;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700843}
844
845status_t Camera2Client::autoFocus() {
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 Talvala174181e2012-08-03 13:53:39 -0700851 int triggerId;
852 {
853 LockedParameters::Key k(mParameters);
854 k.mParameters.currentAfTriggerId = ++k.mParameters.afTriggerCounter;
855 triggerId = k.mParameters.currentAfTriggerId;
856 }
857
858 mDevice->triggerAutofocus(triggerId);
859
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700860 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700861}
862
863status_t Camera2Client::cancelAutoFocus() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700864 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700865 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700866 status_t res;
867 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
868
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700869 int triggerId;
870 {
871 LockedParameters::Key k(mParameters);
872 triggerId = ++k.mParameters.afTriggerCounter;
873 }
874
875 mDevice->triggerCancelAutofocus(triggerId);
876
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700877 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700878}
879
880status_t Camera2Client::takePicture(int msgType) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700881 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700882 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700883 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700884 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700885
886 switch (mState) {
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700887 case DISCONNECTED:
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700888 case STOPPED:
889 case WAITING_FOR_PREVIEW_WINDOW:
890 ALOGE("%s: Camera %d: Cannot take picture without preview enabled",
891 __FUNCTION__, mCameraId);
892 return INVALID_OPERATION;
893 case PREVIEW:
894 case RECORD:
895 // Good to go for takePicture
896 break;
897 case STILL_CAPTURE:
898 case VIDEO_SNAPSHOT:
899 ALOGE("%s: Camera %d: Already taking a picture",
900 __FUNCTION__, mCameraId);
901 return INVALID_OPERATION;
902 }
903
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700904 LockedParameters::Key k(mParameters);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700905
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700906 res = updateCaptureStream(k.mParameters);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700907 if (res != OK) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700908 ALOGE("%s: Camera %d: Can't set up still image stream: %s (%d)",
909 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700910 return res;
911 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700912
913 if (mCaptureRequest == NULL) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700914 res = updateCaptureRequest(k.mParameters);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700915 if (res != OK) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700916 ALOGE("%s: Camera %d: Can't create still image capture request: "
917 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700918 return res;
919 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700920 }
921
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700922 camera_metadata_entry_t outputStreams;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700923 if (mState == PREVIEW) {
924 uint8_t streamIds[2] = { mPreviewStreamId, mCaptureStreamId };
925 res = updateEntry(mCaptureRequest, ANDROID_REQUEST_OUTPUT_STREAMS,
926 &streamIds, 2);
927 } else if (mState == RECORD) {
928 uint8_t streamIds[3] = { mPreviewStreamId, mRecordingStreamId,
929 mCaptureStreamId };
930 res = updateEntry(mCaptureRequest, ANDROID_REQUEST_OUTPUT_STREAMS,
931 &streamIds, 3);
932 }
933
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700934 if (res != OK) {
935 ALOGE("%s: Camera %d: Unable to set up still image capture request: "
936 "%s (%d)",
937 __FUNCTION__, mCameraId, strerror(-res), res);
938 return res;
939 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700940 res = sort_camera_metadata(mCaptureRequest);
941 if (res != OK) {
942 ALOGE("%s: Camera %d: Unable to sort capture request: %s (%d)",
943 __FUNCTION__, mCameraId, strerror(-res), res);
944 return res;
945 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700946
947 camera_metadata_t *captureCopy = clone_camera_metadata(mCaptureRequest);
948 if (captureCopy == NULL) {
949 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device",
950 __FUNCTION__, mCameraId);
951 return NO_MEMORY;
952 }
953
954 if (mState == PREVIEW) {
955 res = mDevice->setStreamingRequest(NULL);
956 if (res != OK) {
957 ALOGE("%s: Camera %d: Unable to stop preview for still capture: "
958 "%s (%d)",
959 __FUNCTION__, mCameraId, strerror(-res), res);
960 return res;
961 }
962 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700963 // TODO: Capture should be atomic with setStreamingRequest here
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700964 res = mDevice->capture(captureCopy);
965 if (res != OK) {
966 ALOGE("%s: Camera %d: Unable to submit still image capture request: "
967 "%s (%d)",
968 __FUNCTION__, mCameraId, strerror(-res), res);
969 return res;
970 }
971
972 switch (mState) {
973 case PREVIEW:
974 mState = STILL_CAPTURE;
975 break;
976 case RECORD:
977 mState = VIDEO_SNAPSHOT;
978 break;
979 default:
980 ALOGE("%s: Camera %d: Unknown state for still capture!",
981 __FUNCTION__, mCameraId);
982 return INVALID_OPERATION;
983 }
984
985 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700986}
987
988status_t Camera2Client::setParameters(const String8& params) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700989 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700990 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700991 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700992 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700993 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
994
995 LockedParameters::Key k(mParameters);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700996
997 CameraParameters newParams(params);
998
999 // TODO: Currently ignoring any changes to supposedly read-only
1000 // parameters such as supported preview sizes, etc. Should probably
1001 // produce an error if they're changed.
1002
1003 /** Extract and verify new parameters */
1004
1005 size_t i;
1006
1007 // PREVIEW_SIZE
1008 int previewWidth, previewHeight;
1009 newParams.getPreviewSize(&previewWidth, &previewHeight);
1010
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001011 if (previewWidth != k.mParameters.previewWidth ||
1012 previewHeight != k.mParameters.previewHeight) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001013 if (mState >= PREVIEW) {
1014 ALOGE("%s: Preview size cannot be updated when preview "
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001015 "is active! (Currently %d x %d, requested %d x %d",
1016 __FUNCTION__,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001017 k.mParameters.previewWidth, k.mParameters.previewHeight,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001018 previewWidth, previewHeight);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001019 return BAD_VALUE;
1020 }
1021 camera_metadata_entry_t availablePreviewSizes =
1022 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
1023 for (i = 0; i < availablePreviewSizes.count; i += 2 ) {
1024 if (availablePreviewSizes.data.i32[i] == previewWidth &&
1025 availablePreviewSizes.data.i32[i+1] == previewHeight) break;
1026 }
1027 if (i == availablePreviewSizes.count) {
1028 ALOGE("%s: Requested preview size %d x %d is not supported",
1029 __FUNCTION__, previewWidth, previewHeight);
1030 return BAD_VALUE;
1031 }
1032 }
1033
1034 // PREVIEW_FPS_RANGE
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001035 int previewFpsRange[2];
1036 int previewFps = 0;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001037 bool fpsRangeChanged = false;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001038 newParams.getPreviewFpsRange(&previewFpsRange[0], &previewFpsRange[1]);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001039 if (previewFpsRange[0] != k.mParameters.previewFpsRange[0] ||
1040 previewFpsRange[1] != k.mParameters.previewFpsRange[1]) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001041 fpsRangeChanged = true;
1042 camera_metadata_entry_t availablePreviewFpsRanges =
1043 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
1044 for (i = 0; i < availablePreviewFpsRanges.count; i += 2) {
1045 if ((availablePreviewFpsRanges.data.i32[i] ==
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001046 previewFpsRange[0]) &&
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001047 (availablePreviewFpsRanges.data.i32[i+1] ==
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001048 previewFpsRange[1]) ) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001049 break;
1050 }
1051 }
1052 if (i == availablePreviewFpsRanges.count) {
1053 ALOGE("%s: Requested preview FPS range %d - %d is not supported",
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001054 __FUNCTION__, previewFpsRange[0], previewFpsRange[1]);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001055 return BAD_VALUE;
1056 }
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001057 previewFps = previewFpsRange[0];
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001058 }
1059
1060 // PREVIEW_FORMAT
1061 int previewFormat = formatStringToEnum(newParams.getPreviewFormat());
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001062 if (previewFormat != k.mParameters.previewFormat) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001063 if (mState >= PREVIEW) {
1064 ALOGE("%s: Preview format cannot be updated when preview "
1065 "is active!", __FUNCTION__);
1066 return BAD_VALUE;
1067 }
1068 camera_metadata_entry_t availableFormats =
1069 staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
1070 for (i = 0; i < availableFormats.count; i++) {
1071 if (availableFormats.data.i32[i] == previewFormat) break;
1072 }
1073 if (i == availableFormats.count) {
1074 ALOGE("%s: Requested preview format %s (0x%x) is not supported",
1075 __FUNCTION__, newParams.getPreviewFormat(), previewFormat);
1076 return BAD_VALUE;
1077 }
1078 }
1079
1080 // PREVIEW_FRAME_RATE
1081 // Deprecated, only use if the preview fps range is unchanged this time.
1082 // The single-value FPS is the same as the minimum of the range.
1083 if (!fpsRangeChanged) {
1084 previewFps = newParams.getPreviewFrameRate();
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001085 if (previewFps != k.mParameters.previewFps) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001086 camera_metadata_entry_t availableFrameRates =
1087 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
1088 for (i = 0; i < availableFrameRates.count; i+=2) {
1089 if (availableFrameRates.data.i32[i] == previewFps) break;
1090 }
1091 if (i == availableFrameRates.count) {
1092 ALOGE("%s: Requested preview frame rate %d is not supported",
1093 __FUNCTION__, previewFps);
1094 return BAD_VALUE;
1095 }
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001096 previewFpsRange[0] = availableFrameRates.data.i32[i];
1097 previewFpsRange[1] = availableFrameRates.data.i32[i+1];
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001098 }
1099 }
1100
1101 // PICTURE_SIZE
1102 int pictureWidth, pictureHeight;
1103 newParams.getPictureSize(&pictureWidth, &pictureHeight);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001104 if (pictureWidth == k.mParameters.pictureWidth ||
1105 pictureHeight == k.mParameters.pictureHeight) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001106 camera_metadata_entry_t availablePictureSizes =
1107 staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES);
1108 for (i = 0; i < availablePictureSizes.count; i+=2) {
1109 if (availablePictureSizes.data.i32[i] == pictureWidth &&
1110 availablePictureSizes.data.i32[i+1] == pictureHeight) break;
1111 }
1112 if (i == availablePictureSizes.count) {
1113 ALOGE("%s: Requested picture size %d x %d is not supported",
1114 __FUNCTION__, pictureWidth, pictureHeight);
1115 return BAD_VALUE;
1116 }
1117 }
1118
1119 // JPEG_THUMBNAIL_WIDTH/HEIGHT
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001120 int jpegThumbSize[2];
1121 jpegThumbSize[0] =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001122 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001123 jpegThumbSize[1] =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001124 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001125 if (jpegThumbSize[0] != k.mParameters.jpegThumbSize[0] ||
1126 jpegThumbSize[1] != k.mParameters.jpegThumbSize[1]) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001127 camera_metadata_entry_t availableJpegThumbSizes =
1128 staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES);
1129 for (i = 0; i < availableJpegThumbSizes.count; i+=2) {
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001130 if (availableJpegThumbSizes.data.i32[i] == jpegThumbSize[0] &&
1131 availableJpegThumbSizes.data.i32[i+1] == jpegThumbSize[1]) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001132 break;
1133 }
1134 }
1135 if (i == availableJpegThumbSizes.count) {
1136 ALOGE("%s: Requested JPEG thumbnail size %d x %d is not supported",
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001137 __FUNCTION__, jpegThumbSize[0], jpegThumbSize[1]);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001138 return BAD_VALUE;
1139 }
1140 }
1141
1142 // JPEG_THUMBNAIL_QUALITY
1143 int jpegThumbQuality =
1144 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
1145 if (jpegThumbQuality < 0 || jpegThumbQuality > 100) {
1146 ALOGE("%s: Requested JPEG thumbnail quality %d is not supported",
1147 __FUNCTION__, jpegThumbQuality);
1148 return BAD_VALUE;
1149 }
1150
1151 // JPEG_QUALITY
1152 int jpegQuality =
1153 newParams.getInt(CameraParameters::KEY_JPEG_QUALITY);
1154 if (jpegQuality < 0 || jpegQuality > 100) {
1155 ALOGE("%s: Requested JPEG quality %d is not supported",
1156 __FUNCTION__, jpegQuality);
1157 return BAD_VALUE;
1158 }
1159
1160 // ROTATION
1161 int jpegRotation =
1162 newParams.getInt(CameraParameters::KEY_ROTATION);
1163 if (jpegRotation != 0 &&
1164 jpegRotation != 90 &&
1165 jpegRotation != 180 &&
1166 jpegRotation != 270) {
1167 ALOGE("%s: Requested picture rotation angle %d is not supported",
1168 __FUNCTION__, jpegRotation);
1169 return BAD_VALUE;
1170 }
1171
1172 // GPS
1173 bool gpsEnabled = false;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001174 double gpsCoordinates[3] = {0,0,0};
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001175 int64_t gpsTimestamp = 0;
1176 String8 gpsProcessingMethod;
1177 const char *gpsLatStr =
1178 newParams.get(CameraParameters::KEY_GPS_LATITUDE);
1179 if (gpsLatStr != NULL) {
1180 const char *gpsLongStr =
1181 newParams.get(CameraParameters::KEY_GPS_LONGITUDE);
1182 const char *gpsAltitudeStr =
1183 newParams.get(CameraParameters::KEY_GPS_ALTITUDE);
1184 const char *gpsTimeStr =
1185 newParams.get(CameraParameters::KEY_GPS_TIMESTAMP);
1186 const char *gpsProcMethodStr =
1187 newParams.get(CameraParameters::KEY_GPS_PROCESSING_METHOD);
1188 if (gpsLongStr == NULL ||
1189 gpsAltitudeStr == NULL ||
1190 gpsTimeStr == NULL ||
1191 gpsProcMethodStr == NULL) {
1192 ALOGE("%s: Incomplete set of GPS parameters provided",
1193 __FUNCTION__);
1194 return BAD_VALUE;
1195 }
1196 char *endPtr;
1197 errno = 0;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001198 gpsCoordinates[0] = strtod(gpsLatStr, &endPtr);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001199 if (errno || endPtr == gpsLatStr) {
1200 ALOGE("%s: Malformed GPS latitude: %s", __FUNCTION__, gpsLatStr);
1201 return BAD_VALUE;
1202 }
1203 errno = 0;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001204 gpsCoordinates[1] = strtod(gpsLongStr, &endPtr);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001205 if (errno || endPtr == gpsLongStr) {
1206 ALOGE("%s: Malformed GPS longitude: %s", __FUNCTION__, gpsLongStr);
1207 return BAD_VALUE;
1208 }
1209 errno = 0;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001210 gpsCoordinates[2] = strtod(gpsAltitudeStr, &endPtr);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001211 if (errno || endPtr == gpsAltitudeStr) {
1212 ALOGE("%s: Malformed GPS altitude: %s", __FUNCTION__,
1213 gpsAltitudeStr);
1214 return BAD_VALUE;
1215 }
1216 errno = 0;
1217 gpsTimestamp = strtoll(gpsTimeStr, &endPtr, 10);
1218 if (errno || endPtr == gpsTimeStr) {
1219 ALOGE("%s: Malformed GPS timestamp: %s", __FUNCTION__, gpsTimeStr);
1220 return BAD_VALUE;
1221 }
1222 gpsProcessingMethod = gpsProcMethodStr;
1223
1224 gpsEnabled = true;
1225 }
1226
1227 // WHITE_BALANCE
1228 int wbMode = wbModeStringToEnum(
1229 newParams.get(CameraParameters::KEY_WHITE_BALANCE) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001230 if (wbMode != k.mParameters.wbMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001231 camera_metadata_entry_t availableWbModes =
1232 staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
1233 for (i = 0; i < availableWbModes.count; i++) {
1234 if (wbMode == availableWbModes.data.u8[i]) break;
1235 }
1236 if (i == availableWbModes.count) {
1237 ALOGE("%s: Requested white balance mode %s is not supported",
1238 __FUNCTION__,
1239 newParams.get(CameraParameters::KEY_WHITE_BALANCE));
1240 return BAD_VALUE;
1241 }
1242 }
1243
1244 // EFFECT
1245 int effectMode = effectModeStringToEnum(
1246 newParams.get(CameraParameters::KEY_EFFECT) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001247 if (effectMode != k.mParameters.effectMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001248 camera_metadata_entry_t availableEffectModes =
1249 staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
1250 for (i = 0; i < availableEffectModes.count; i++) {
1251 if (effectMode == availableEffectModes.data.u8[i]) break;
1252 }
1253 if (i == availableEffectModes.count) {
1254 ALOGE("%s: Requested effect mode \"%s\" is not supported",
1255 __FUNCTION__,
1256 newParams.get(CameraParameters::KEY_EFFECT) );
1257 return BAD_VALUE;
1258 }
1259 }
1260
1261 // ANTIBANDING
1262 int antibandingMode = abModeStringToEnum(
1263 newParams.get(CameraParameters::KEY_ANTIBANDING) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001264 if (antibandingMode != k.mParameters.antibandingMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001265 camera_metadata_entry_t availableAbModes =
1266 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
1267 for (i = 0; i < availableAbModes.count; i++) {
1268 if (antibandingMode == availableAbModes.data.u8[i]) break;
1269 }
1270 if (i == availableAbModes.count) {
1271 ALOGE("%s: Requested antibanding mode \"%s\" is not supported",
1272 __FUNCTION__,
1273 newParams.get(CameraParameters::KEY_ANTIBANDING));
1274 return BAD_VALUE;
1275 }
1276 }
1277
1278 // SCENE_MODE
1279 int sceneMode = sceneModeStringToEnum(
1280 newParams.get(CameraParameters::KEY_SCENE_MODE) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001281 if (sceneMode != k.mParameters.sceneMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001282 camera_metadata_entry_t availableSceneModes =
1283 staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
1284 for (i = 0; i < availableSceneModes.count; i++) {
1285 if (sceneMode == availableSceneModes.data.u8[i]) break;
1286 }
1287 if (i == availableSceneModes.count) {
1288 ALOGE("%s: Requested scene mode \"%s\" is not supported",
1289 __FUNCTION__,
1290 newParams.get(CameraParameters::KEY_SCENE_MODE));
1291 return BAD_VALUE;
1292 }
1293 }
1294
1295 // FLASH_MODE
1296 Parameters::flashMode_t flashMode = flashModeStringToEnum(
1297 newParams.get(CameraParameters::KEY_FLASH_MODE) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001298 if (flashMode != k.mParameters.flashMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001299 camera_metadata_entry_t flashAvailable =
1300 staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
1301 if (!flashAvailable.data.u8[0] &&
1302 flashMode != Parameters::FLASH_MODE_OFF) {
1303 ALOGE("%s: Requested flash mode \"%s\" is not supported: "
1304 "No flash on device", __FUNCTION__,
1305 newParams.get(CameraParameters::KEY_FLASH_MODE));
1306 return BAD_VALUE;
1307 } else if (flashMode == Parameters::FLASH_MODE_RED_EYE) {
1308 camera_metadata_entry_t availableAeModes =
1309 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
1310 for (i = 0; i < availableAeModes.count; i++) {
1311 if (flashMode == availableAeModes.data.u8[i]) break;
1312 }
1313 if (i == availableAeModes.count) {
1314 ALOGE("%s: Requested flash mode \"%s\" is not supported",
1315 __FUNCTION__,
1316 newParams.get(CameraParameters::KEY_FLASH_MODE));
1317 return BAD_VALUE;
1318 }
1319 } else if (flashMode == -1) {
1320 ALOGE("%s: Requested flash mode \"%s\" is unknown",
1321 __FUNCTION__,
1322 newParams.get(CameraParameters::KEY_FLASH_MODE));
1323 return BAD_VALUE;
1324 }
1325 }
1326
1327 // FOCUS_MODE
1328 Parameters::focusMode_t focusMode = focusModeStringToEnum(
1329 newParams.get(CameraParameters::KEY_FOCUS_MODE));
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001330 if (focusMode != k.mParameters.focusMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001331 if (focusMode != Parameters::FOCUS_MODE_FIXED) {
1332 camera_metadata_entry_t minFocusDistance =
1333 staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE);
1334 if (minFocusDistance.data.f[0] == 0) {
1335 ALOGE("%s: Requested focus mode \"%s\" is not available: "
1336 "fixed focus lens",
1337 __FUNCTION__,
1338 newParams.get(CameraParameters::KEY_FOCUS_MODE));
1339 return BAD_VALUE;
1340 } else if (focusMode != Parameters::FOCUS_MODE_INFINITY) {
1341 camera_metadata_entry_t availableFocusModes =
1342 staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
1343 for (i = 0; i < availableFocusModes.count; i++) {
1344 if (focusMode == availableFocusModes.data.u8[i]) break;
1345 }
1346 if (i == availableFocusModes.count) {
1347 ALOGE("%s: Requested focus mode \"%s\" is not supported",
1348 __FUNCTION__,
1349 newParams.get(CameraParameters::KEY_FOCUS_MODE));
1350 return BAD_VALUE;
1351 }
1352 }
1353 }
1354 }
1355
1356 // FOCUS_AREAS
1357 Vector<Parameters::Area> focusingAreas;
1358 res = parseAreas(newParams.get(CameraParameters::KEY_FOCUS_AREAS),
1359 &focusingAreas);
1360 size_t max3aRegions =
1361 (size_t)staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1).data.i32[0];
1362 if (res == OK) res = validateAreas(focusingAreas, max3aRegions);
1363 if (res != OK) {
1364 ALOGE("%s: Requested focus areas are malformed: %s",
1365 __FUNCTION__, newParams.get(CameraParameters::KEY_FOCUS_AREAS));
1366 return BAD_VALUE;
1367 }
1368
1369 // EXPOSURE_COMPENSATION
1370 int exposureCompensation =
1371 newParams.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION);
1372 camera_metadata_entry_t exposureCompensationRange =
1373 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE);
1374 if (exposureCompensation < exposureCompensationRange.data.i32[0] ||
1375 exposureCompensation > exposureCompensationRange.data.i32[1]) {
1376 ALOGE("%s: Requested exposure compensation index is out of bounds: %d",
1377 __FUNCTION__, exposureCompensation);
1378 return BAD_VALUE;
1379 }
1380
1381 // AUTO_EXPOSURE_LOCK (always supported)
1382 bool autoExposureLock = boolFromString(
1383 newParams.get(CameraParameters::KEY_AUTO_EXPOSURE_LOCK));
1384
1385 // AUTO_WHITEBALANCE_LOCK (always supported)
1386 bool autoWhiteBalanceLock = boolFromString(
1387 newParams.get(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK));
1388
1389 // METERING_AREAS
1390 Vector<Parameters::Area> meteringAreas;
1391 res = parseAreas(newParams.get(CameraParameters::KEY_METERING_AREAS),
1392 &meteringAreas);
1393 if (res == OK) res = validateAreas(focusingAreas, max3aRegions);
1394 if (res != OK) {
1395 ALOGE("%s: Requested metering areas are malformed: %s",
1396 __FUNCTION__,
1397 newParams.get(CameraParameters::KEY_METERING_AREAS));
1398 return BAD_VALUE;
1399 }
1400
1401 // ZOOM
1402 int zoom = newParams.getInt(CameraParameters::KEY_ZOOM);
1403 if (zoom < 0 || zoom > (int)NUM_ZOOM_STEPS) {
1404 ALOGE("%s: Requested zoom level %d is not supported",
1405 __FUNCTION__, zoom);
1406 return BAD_VALUE;
1407 }
1408
1409 // VIDEO_SIZE
1410 int videoWidth, videoHeight;
1411 newParams.getVideoSize(&videoWidth, &videoHeight);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001412 if (videoWidth != k.mParameters.videoWidth ||
1413 videoHeight != k.mParameters.videoHeight) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001414 if (mState == RECORD) {
1415 ALOGE("%s: Video size cannot be updated when recording is active!",
1416 __FUNCTION__);
1417 return BAD_VALUE;
1418 }
1419 camera_metadata_entry_t availableVideoSizes =
1420 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
1421 for (i = 0; i < availableVideoSizes.count; i += 2 ) {
1422 if (availableVideoSizes.data.i32[i] == videoWidth &&
1423 availableVideoSizes.data.i32[i+1] == videoHeight) break;
1424 }
1425 if (i == availableVideoSizes.count) {
1426 ALOGE("%s: Requested video size %d x %d is not supported",
1427 __FUNCTION__, videoWidth, videoHeight);
1428 return BAD_VALUE;
1429 }
1430 }
1431
1432 // RECORDING_HINT (always supported)
1433 bool recordingHint = boolFromString(
1434 newParams.get(CameraParameters::KEY_RECORDING_HINT) );
1435
1436 // VIDEO_STABILIZATION
1437 bool videoStabilization = boolFromString(
1438 newParams.get(CameraParameters::KEY_VIDEO_STABILIZATION) );
1439 camera_metadata_entry_t availableVideoStabilizationModes =
1440 staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
1441 if (videoStabilization && availableVideoStabilizationModes.count == 1) {
1442 ALOGE("%s: Video stabilization not supported", __FUNCTION__);
1443 }
1444
1445 /** Update internal parameters */
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001446
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001447 k.mParameters.previewWidth = previewWidth;
1448 k.mParameters.previewHeight = previewHeight;
1449 k.mParameters.previewFpsRange[0] = previewFpsRange[0];
1450 k.mParameters.previewFpsRange[1] = previewFpsRange[1];
1451 k.mParameters.previewFps = previewFps;
1452 k.mParameters.previewFormat = previewFormat;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001453
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001454 k.mParameters.pictureWidth = pictureWidth;
1455 k.mParameters.pictureHeight = pictureHeight;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001456
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001457 k.mParameters.jpegThumbSize[0] = jpegThumbSize[0];
1458 k.mParameters.jpegThumbSize[1] = jpegThumbSize[1];
1459 k.mParameters.jpegQuality = jpegQuality;
1460 k.mParameters.jpegThumbQuality = jpegThumbQuality;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001461
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001462 k.mParameters.gpsEnabled = gpsEnabled;
1463 k.mParameters.gpsCoordinates[0] = gpsCoordinates[0];
1464 k.mParameters.gpsCoordinates[1] = gpsCoordinates[1];
1465 k.mParameters.gpsCoordinates[2] = gpsCoordinates[2];
1466 k.mParameters.gpsTimestamp = gpsTimestamp;
1467 k.mParameters.gpsProcessingMethod = gpsProcessingMethod;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001468
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001469 k.mParameters.wbMode = wbMode;
1470 k.mParameters.effectMode = effectMode;
1471 k.mParameters.antibandingMode = antibandingMode;
1472 k.mParameters.sceneMode = sceneMode;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001473
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001474 k.mParameters.flashMode = flashMode;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001475 if (focusMode != k.mParameters.focusMode) {
1476 k.mParameters.currentAfTriggerId = -1;
1477 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001478 k.mParameters.focusMode = focusMode;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001479
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001480 k.mParameters.focusingAreas = focusingAreas;
1481 k.mParameters.exposureCompensation = exposureCompensation;
1482 k.mParameters.autoExposureLock = autoExposureLock;
1483 k.mParameters.autoWhiteBalanceLock = autoWhiteBalanceLock;
1484 k.mParameters.meteringAreas = meteringAreas;
1485 k.mParameters.zoom = zoom;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001486
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001487 k.mParameters.videoWidth = videoWidth;
1488 k.mParameters.videoHeight = videoHeight;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001489
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001490 k.mParameters.recordingHint = recordingHint;
1491 k.mParameters.videoStabilization = videoStabilization;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001492
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001493 res = updatePreviewRequest(k.mParameters);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001494 if (res != OK) {
1495 ALOGE("%s: Camera %d: Unable to update preview request: %s (%d)",
1496 __FUNCTION__, mCameraId, strerror(-res), res);
1497 return res;
1498 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001499 res = updateCaptureRequest(k.mParameters);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001500 if (res != OK) {
1501 ALOGE("%s: Camera %d: Unable to update capture request: %s (%d)",
1502 __FUNCTION__, mCameraId, strerror(-res), res);
1503 return res;
1504 }
1505
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001506 res = updateRecordingRequest(k.mParameters);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001507 if (res != OK) {
1508 ALOGE("%s: Camera %d: Unable to update recording request: %s (%d)",
1509 __FUNCTION__, mCameraId, strerror(-res), res);
1510 return res;
1511 }
1512
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001513 if (mState == PREVIEW) {
1514 res = mDevice->setStreamingRequest(mPreviewRequest);
1515 if (res != OK) {
1516 ALOGE("%s: Camera %d: Error streaming new preview request: %s (%d)",
1517 __FUNCTION__, mCameraId, strerror(-res), res);
1518 return res;
1519 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001520 } else if (mState == RECORD || mState == VIDEO_SNAPSHOT) {
1521 res = mDevice->setStreamingRequest(mRecordingRequest);
1522 if (res != OK) {
1523 ALOGE("%s: Camera %d: Error streaming new record request: %s (%d)",
1524 __FUNCTION__, mCameraId, strerror(-res), res);
1525 return res;
1526 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001527 }
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001528
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001529 k.mParameters.paramsFlattened = params;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001530
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001531 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001532}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001533
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001534String8 Camera2Client::getParameters() const {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001535 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001536 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001537 if ( checkPid(__FUNCTION__) != OK) return String8();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001538
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001539 LockedParameters::ReadKey k(mParameters);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001540
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001541 // TODO: Deal with focus distances
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001542 return k.mParameters.paramsFlattened;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001543}
1544
1545status_t Camera2Client::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001546 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001547 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001548 status_t res;
1549 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001550
1551 ALOGV("%s: Camera %d: Command %d (%d, %d)", __FUNCTION__, mCameraId,
1552 cmd, arg1, arg2);
1553
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001554 switch (cmd) {
1555 case CAMERA_CMD_START_SMOOTH_ZOOM:
1556 return commandStartSmoothZoomL();
1557 case CAMERA_CMD_STOP_SMOOTH_ZOOM:
1558 return commandStopSmoothZoomL();
1559 case CAMERA_CMD_SET_DISPLAY_ORIENTATION:
1560 return commandSetDisplayOrientationL(arg1);
1561 case CAMERA_CMD_ENABLE_SHUTTER_SOUND:
1562 return commandEnableShutterSoundL(arg1 == 1);
1563 case CAMERA_CMD_PLAY_RECORDING_SOUND:
1564 return commandPlayRecordingSoundL();
1565 case CAMERA_CMD_START_FACE_DETECTION:
1566 return commandStartFaceDetectionL(arg1);
1567 case CAMERA_CMD_STOP_FACE_DETECTION:
1568 return commandStopFaceDetectionL();
1569 case CAMERA_CMD_ENABLE_FOCUS_MOVE_MSG:
1570 return commandEnableFocusMoveMsgL(arg1 == 1);
1571 case CAMERA_CMD_PING:
1572 return commandPingL();
1573 case CAMERA_CMD_SET_VIDEO_BUFFER_COUNT:
1574 return commandSetVideoBufferCountL(arg1);
1575 default:
1576 ALOGE("%s: Unknown command %d (arguments %d, %d)",
1577 __FUNCTION__, cmd, arg1, arg2);
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001578 return BAD_VALUE;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001579 }
1580}
James Dong983cf232012-08-01 16:39:55 -07001581
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001582status_t Camera2Client::commandStartSmoothZoomL() {
1583 ALOGE("%s: Unimplemented!", __FUNCTION__);
1584 return OK;
1585}
James Dong983cf232012-08-01 16:39:55 -07001586
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001587status_t Camera2Client::commandStopSmoothZoomL() {
1588 ALOGE("%s: Unimplemented!", __FUNCTION__);
1589 return OK;
1590}
James Dong983cf232012-08-01 16:39:55 -07001591
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001592status_t Camera2Client::commandSetDisplayOrientationL(int degrees) {
1593 LockedParameters::Key k(mParameters);
1594 int transform = degToTransform(degrees,
1595 mCameraFacing == CAMERA_FACING_FRONT);
1596 if (transform == -1) {
1597 ALOGE("%s: Camera %d: Error setting %d as display orientation value",
1598 __FUNCTION__, mCameraId, degrees);
1599 return BAD_VALUE;
1600 }
1601 if (transform != k.mParameters.previewTransform &&
1602 mPreviewStreamId != NO_STREAM) {
1603 mDevice->setStreamTransform(mPreviewStreamId, transform);
1604 }
1605 k.mParameters.previewTransform = transform;
1606 return OK;
1607}
1608
1609status_t Camera2Client::commandEnableShutterSoundL(bool enable) {
1610 LockedParameters::Key k(mParameters);
1611 if (enable) {
1612 k.mParameters.playShutterSound = true;
James Dong983cf232012-08-01 16:39:55 -07001613 return OK;
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001614 }
1615
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001616 // Disabling shutter sound may not be allowed. In that case only
1617 // allow the mediaserver process to disable the sound.
1618 char value[PROPERTY_VALUE_MAX];
1619 property_get("ro.camera.sound.forced", value, "0");
1620 if (strncmp(value, "0", 2) != 0) {
1621 // Disabling shutter sound is not allowed. Deny if the current
1622 // process is not mediaserver.
1623 if (getCallingPid() != getpid()) {
1624 ALOGE("Failed to disable shutter sound. Permission denied (pid %d)",
1625 getCallingPid());
1626 return PERMISSION_DENIED;
1627 }
1628 }
1629
1630 k.mParameters.playShutterSound = false;
1631 return OK;
1632}
1633
1634status_t Camera2Client::commandPlayRecordingSoundL() {
1635 mCameraService->playSound(CameraService::SOUND_RECORDING);
1636 return OK;
1637}
1638
1639status_t Camera2Client::commandStartFaceDetectionL(int type) {
1640 ALOGE("%s: Unimplemented!", __FUNCTION__);
1641 return OK;
1642}
1643
1644status_t Camera2Client::commandStopFaceDetectionL() {
1645 ALOGE("%s: Unimplemented!", __FUNCTION__);
1646 return OK;
1647}
1648
1649status_t Camera2Client::commandEnableFocusMoveMsgL(bool enable) {
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001650 LockedParameters::Key k(mParameters);
1651 k.mParameters.enableFocusMoveMessages = enable;
1652
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001653 return OK;
1654}
1655
1656status_t Camera2Client::commandPingL() {
1657 // Always ping back if access is proper and device is alive
1658 if (mState != DISCONNECTED) {
1659 return OK;
1660 } else {
1661 return NO_INIT;
1662 }
1663}
1664
1665status_t Camera2Client::commandSetVideoBufferCountL(size_t count) {
James Dong8da4cd72012-08-04 19:58:07 -07001666 if (recordingEnabledL()) {
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001667 ALOGE("%s: Camera %d: Error setting video buffer count after "
1668 "recording was started", __FUNCTION__, mCameraId);
1669 return INVALID_OPERATION;
1670 }
1671
1672 // 32 is the current upper limit on the video buffer count for BufferQueue
1673 if (count > 32) {
1674 ALOGE("%s: Camera %d: Error setting %d as video buffer count value",
1675 __FUNCTION__, mCameraId, count);
1676 return BAD_VALUE;
1677 }
1678
1679 // Need to reallocate memory for heap
1680 if (mRecordingHeapCount != count) {
1681 if (mRecordingHeap != 0) {
1682 mRecordingHeap.clear();
1683 mRecordingHeap = NULL;
1684 }
1685 mRecordingHeapCount = count;
1686 }
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001687
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001688 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001689}
1690
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001691/** Device-related methods */
1692
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -07001693void Camera2Client::notifyError(int errorCode, int arg1, int arg2) {
1694 ALOGE("Error condition %d reported by HAL, arguments %d, %d", errorCode, arg1, arg2);
1695}
1696
1697void Camera2Client::notifyShutter(int frameNumber, nsecs_t timestamp) {
1698 ALOGV("%s: Shutter notification for frame %d at time %lld", __FUNCTION__,
1699 frameNumber, timestamp);
1700}
1701
1702void Camera2Client::notifyAutoFocus(uint8_t newState, int triggerId) {
1703 ALOGV("%s: Autofocus state now %d, last trigger %d",
1704 __FUNCTION__, newState, triggerId);
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001705 bool sendCompletedMessage = false;
1706 bool sendMovingMessage = false;
1707
1708 bool success = false;
1709 bool afInMotion = false;
1710 {
1711 LockedParameters::Key k(mParameters);
1712 switch (k.mParameters.focusMode) {
1713 case Parameters::FOCUS_MODE_AUTO:
1714 case Parameters::FOCUS_MODE_MACRO:
1715 // Don't send notifications upstream if they're not for the current AF
1716 // trigger. For example, if cancel was called in between, or if we
1717 // already sent a notification about this AF call.
1718 if (triggerId != k.mParameters.currentAfTriggerId) break;
1719 switch (newState) {
1720 case ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED:
1721 success = true;
1722 // no break
1723 case ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
1724 sendCompletedMessage = true;
1725 k.mParameters.currentAfTriggerId = -1;
1726 break;
1727 case ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN:
1728 // Just starting focusing, ignore
1729 break;
1730 case ANDROID_CONTROL_AF_STATE_INACTIVE:
1731 case ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN:
1732 case ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED:
1733 default:
1734 // Unexpected in AUTO/MACRO mode
1735 ALOGE("%s: Unexpected AF state transition in AUTO/MACRO mode: %d",
1736 __FUNCTION__, newState);
1737 break;
1738 }
1739 break;
1740 case Parameters::FOCUS_MODE_CONTINUOUS_VIDEO:
1741 case Parameters::FOCUS_MODE_CONTINUOUS_PICTURE:
1742 switch (newState) {
1743 case ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED:
1744 success = true;
1745 // no break
1746 case ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
1747 // Don't send notifications upstream if they're not for
1748 // the current AF trigger. For example, if cancel was
1749 // called in between, or if we already sent a
1750 // notification about this AF call.
1751 // Send both a 'AF done' callback and a 'AF move' callback
1752 if (triggerId != k.mParameters.currentAfTriggerId) break;
1753 sendCompletedMessage = true;
1754 afInMotion = false;
1755 if (k.mParameters.enableFocusMoveMessages &&
1756 k.mParameters.afInMotion) {
1757 sendMovingMessage = true;
1758 }
1759 k.mParameters.currentAfTriggerId = -1;
1760 break;
1761 case ANDROID_CONTROL_AF_STATE_INACTIVE:
1762 // Cancel was called, or we switched state; care if
1763 // currently moving
1764 afInMotion = false;
1765 if (k.mParameters.enableFocusMoveMessages &&
1766 k.mParameters.afInMotion) {
1767 sendMovingMessage = true;
1768 }
1769 break;
1770 case ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN:
1771 // Start passive scan, inform upstream
1772 afInMotion = true;
1773 // no break
1774 case ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED:
1775 // Stop passive scan, inform upstream
1776 if (k.mParameters.enableFocusMoveMessages) {
1777 sendMovingMessage = true;
1778 }
1779 break;
1780 }
1781 k.mParameters.afInMotion = afInMotion;
1782 break;
1783 case Parameters::FOCUS_MODE_EDOF:
1784 case Parameters::FOCUS_MODE_INFINITY:
1785 case Parameters::FOCUS_MODE_FIXED:
1786 default:
1787 if (newState != ANDROID_CONTROL_AF_STATE_INACTIVE) {
1788 ALOGE("%s: Unexpected AF state change %d (ID %d) in focus mode %d",
1789 __FUNCTION__, newState, triggerId, k.mParameters.focusMode);
1790 }
1791 }
1792 }
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001793 if (sendMovingMessage) {
1794 mCameraClient->notifyCallback(CAMERA_MSG_FOCUS_MOVE,
1795 afInMotion ? 1 : 0, 0);
1796 }
Eino-Ville Talvala603b12e2012-08-08 09:25:58 -07001797 if (sendCompletedMessage) {
1798 mCameraClient->notifyCallback(CAMERA_MSG_FOCUS, success ? 1 : 0, 0);
1799 }
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -07001800}
1801
1802void Camera2Client::notifyAutoExposure(uint8_t newState, int triggerId) {
1803 ALOGV("%s: Autoexposure state now %d, last trigger %d",
1804 __FUNCTION__, newState, triggerId);
1805}
1806
1807void Camera2Client::notifyAutoWhitebalance(uint8_t newState, int triggerId) {
1808 ALOGV("%s: Auto-whitebalance state now %d, last trigger %d",
1809 __FUNCTION__, newState, triggerId);
1810}
1811
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001812void Camera2Client::onCaptureAvailable() {
1813 ATRACE_CALL();
1814 status_t res;
1815 sp<ICameraClient> currentClient;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001816 ALOGV("%s: Camera %d: Still capture available", __FUNCTION__, mCameraId);
1817
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001818 CpuConsumer::LockedBuffer imgBuffer;
1819 {
1820 Mutex::Autolock icl(mICameraLock);
1821
1822 // TODO: Signal errors here upstream
1823 if (mState != STILL_CAPTURE && mState != VIDEO_SNAPSHOT) {
1824 ALOGE("%s: Camera %d: Still image produced unexpectedly!",
1825 __FUNCTION__, mCameraId);
1826 return;
1827 }
1828
1829 res = mCaptureConsumer->lockNextBuffer(&imgBuffer);
1830 if (res != OK) {
1831 ALOGE("%s: Camera %d: Error receiving still image buffer: %s (%d)",
1832 __FUNCTION__, mCameraId, strerror(-res), res);
1833 return;
1834 }
1835
1836 if (imgBuffer.format != HAL_PIXEL_FORMAT_BLOB) {
1837 ALOGE("%s: Camera %d: Unexpected format for still image: "
1838 "%x, expected %x", __FUNCTION__, mCameraId,
1839 imgBuffer.format,
1840 HAL_PIXEL_FORMAT_BLOB);
1841 mCaptureConsumer->unlockBuffer(imgBuffer);
1842 return;
1843 }
1844
1845 // TODO: Optimize this to avoid memcopy
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001846 void* captureMemory = mCaptureHeap->mHeap->getBase();
1847 size_t size = mCaptureHeap->mHeap->getSize();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001848 memcpy(captureMemory, imgBuffer.data, size);
1849
1850 mCaptureConsumer->unlockBuffer(imgBuffer);
1851
1852 currentClient = mCameraClient;
1853 switch (mState) {
1854 case STILL_CAPTURE:
1855 mState = STOPPED;
1856 break;
1857 case VIDEO_SNAPSHOT:
1858 mState = RECORD;
1859 break;
1860 default:
1861 ALOGE("%s: Camera %d: Unexpected state %d", __FUNCTION__,
1862 mCameraId, mState);
1863 break;
1864 }
1865 }
1866 // Call outside mICameraLock to allow re-entrancy from notification
1867 if (currentClient != 0) {
1868 currentClient->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001869 mCaptureHeap->mBuffers[0], NULL);
1870 }
1871}
1872
1873void Camera2Client::onRecordingFrameAvailable() {
1874 ATRACE_CALL();
1875 status_t res;
1876 sp<ICameraClient> currentClient;
1877 size_t heapIdx = 0;
1878 nsecs_t timestamp;
1879 {
1880 Mutex::Autolock icl(mICameraLock);
1881 // TODO: Signal errors here upstream
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001882 bool discardData = false;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001883 if (mState != RECORD && mState != VIDEO_SNAPSHOT) {
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001884 ALOGV("%s: Camera %d: Discarding recording image buffers received after "
1885 "recording done",
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001886 __FUNCTION__, mCameraId);
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001887 discardData = true;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001888 }
1889
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001890 buffer_handle_t imgBuffer;
1891 res = mRecordingConsumer->getNextBuffer(&imgBuffer, &timestamp);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001892 if (res != OK) {
1893 ALOGE("%s: Camera %d: Error receiving recording buffer: %s (%d)",
1894 __FUNCTION__, mCameraId, strerror(-res), res);
1895 return;
1896 }
1897
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001898 if (discardData) {
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001899 mRecordingConsumer->freeBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001900 return;
1901 }
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001902
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001903 if (mRecordingHeap == 0) {
1904 const size_t bufferSize = 4 + sizeof(buffer_handle_t);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001905 ALOGV("%s: Camera %d: Creating recording heap with %d buffers of "
1906 "size %d bytes", __FUNCTION__, mCameraId,
James Dong983cf232012-08-01 16:39:55 -07001907 mRecordingHeapCount, bufferSize);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001908 if (mRecordingHeap != 0) {
1909 ALOGV("%s: Camera %d: Previous heap has size %d "
1910 "(new will be %d) bytes", __FUNCTION__, mCameraId,
1911 mRecordingHeap->mHeap->getSize(),
James Dong983cf232012-08-01 16:39:55 -07001912 bufferSize * mRecordingHeapCount);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001913 }
1914 // Need to allocate memory for heap
1915 mRecordingHeap.clear();
1916
James Dong983cf232012-08-01 16:39:55 -07001917 mRecordingHeap = new Camera2Heap(bufferSize, mRecordingHeapCount,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001918 "Camera2Client::RecordingHeap");
1919 if (mRecordingHeap->mHeap->getSize() == 0) {
1920 ALOGE("%s: Camera %d: Unable to allocate memory for recording",
1921 __FUNCTION__, mCameraId);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001922 mRecordingConsumer->freeBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001923 return;
1924 }
1925 mRecordingHeapHead = 0;
James Dong983cf232012-08-01 16:39:55 -07001926 mRecordingHeapFree = mRecordingHeapCount;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001927 }
1928
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001929 if ( mRecordingHeapFree == 0) {
1930 ALOGE("%s: Camera %d: No free recording buffers, dropping frame",
1931 __FUNCTION__, mCameraId);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001932 mRecordingConsumer->freeBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001933 return;
1934 }
1935 heapIdx = mRecordingHeapHead;
James Dong983cf232012-08-01 16:39:55 -07001936 mRecordingHeapHead = (mRecordingHeapHead + 1) % mRecordingHeapCount;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001937 mRecordingHeapFree--;
1938
1939 ALOGV("%s: Camera %d: Timestamp %lld",
1940 __FUNCTION__, mCameraId, timestamp);
1941
1942 ssize_t offset;
1943 size_t size;
1944 sp<IMemoryHeap> heap =
1945 mRecordingHeap->mBuffers[heapIdx]->getMemory(&offset,
1946 &size);
1947
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001948 uint8_t *data = (uint8_t*)heap->getBase() + offset;
1949 uint32_t type = kMetadataBufferTypeGrallocSource;
1950 memcpy(data, &type, 4);
1951 memcpy(data + 4, &imgBuffer, sizeof(buffer_handle_t));
1952 ALOGV("%s: Camera %d: Sending out buffer_handle_t %p",
Eino-Ville Talvala803cbf62012-07-25 15:23:36 -07001953 __FUNCTION__, mCameraId, imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001954 currentClient = mCameraClient;
1955 }
1956 // Call outside mICameraLock to allow re-entrancy from notification
1957 if (currentClient != 0) {
1958 currentClient->dataCallbackTimestamp(timestamp,
1959 CAMERA_MSG_VIDEO_FRAME,
1960 mRecordingHeap->mBuffers[heapIdx]);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001961 }
1962}
1963
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001964camera_metadata_entry_t Camera2Client::staticInfo(uint32_t tag,
1965 size_t minCount, size_t maxCount) {
1966 status_t res;
1967 camera_metadata_entry_t entry;
1968 res = find_camera_metadata_entry(mDevice->info(),
1969 tag,
1970 &entry);
1971 if (CC_UNLIKELY( res != OK )) {
1972 const char* tagSection = get_camera_metadata_section_name(tag);
1973 if (tagSection == NULL) tagSection = "<unknown>";
1974 const char* tagName = get_camera_metadata_tag_name(tag);
1975 if (tagName == NULL) tagName = "<unknown>";
1976
1977 ALOGE("Error finding static metadata entry '%s.%s' (%x): %s (%d)",
1978 tagSection, tagName, tag, strerror(-res), res);
1979 entry.count = 0;
1980 entry.data.u8 = NULL;
1981 } else if (CC_UNLIKELY(
1982 (minCount != 0 && entry.count < minCount) ||
1983 (maxCount != 0 && entry.count > maxCount) ) ) {
1984 const char* tagSection = get_camera_metadata_section_name(tag);
1985 if (tagSection == NULL) tagSection = "<unknown>";
1986 const char* tagName = get_camera_metadata_tag_name(tag);
1987 if (tagName == NULL) tagName = "<unknown>";
1988 ALOGE("Malformed static metadata entry '%s.%s' (%x):"
1989 "Expected between %d and %d values, but got %d values",
1990 tagSection, tagName, tag, minCount, maxCount, entry.count);
1991 entry.count = 0;
1992 entry.data.u8 = NULL;
1993 }
1994
1995 return entry;
1996}
1997
1998/** Utility methods */
1999
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002000
2001status_t Camera2Client::buildDefaultParameters() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07002002 ATRACE_CALL();
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002003 LockedParameters::Key k(mParameters);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07002004
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002005 status_t res;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002006 CameraParameters params;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002007
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002008 camera_metadata_entry_t availableProcessedSizes =
2009 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES, 2);
2010 if (!availableProcessedSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002011
2012 // TODO: Pick more intelligently
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002013 k.mParameters.previewWidth = availableProcessedSizes.data.i32[0];
2014 k.mParameters.previewHeight = availableProcessedSizes.data.i32[1];
2015 k.mParameters.videoWidth = k.mParameters.previewWidth;
2016 k.mParameters.videoHeight = k.mParameters.previewHeight;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002017
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002018 params.setPreviewSize(k.mParameters.previewWidth, k.mParameters.previewHeight);
2019 params.setVideoSize(k.mParameters.videoWidth, k.mParameters.videoHeight);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002020 params.set(CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO,
2021 String8::format("%dx%d",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002022 k.mParameters.previewWidth, k.mParameters.previewHeight));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002023 {
2024 String8 supportedPreviewSizes;
2025 for (size_t i=0; i < availableProcessedSizes.count; i += 2) {
2026 if (i != 0) supportedPreviewSizes += ",";
2027 supportedPreviewSizes += String8::format("%dx%d",
2028 availableProcessedSizes.data.i32[i],
2029 availableProcessedSizes.data.i32[i+1]);
2030 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002031 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002032 supportedPreviewSizes);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002033 params.set(CameraParameters::KEY_SUPPORTED_VIDEO_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002034 supportedPreviewSizes);
2035 }
2036
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002037 camera_metadata_entry_t availableFpsRanges =
2038 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
2039 if (!availableFpsRanges.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002040
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002041 k.mParameters.previewFpsRange[0] = availableFpsRanges.data.i32[0];
2042 k.mParameters.previewFpsRange[1] = availableFpsRanges.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002043
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002044 params.set(CameraParameters::KEY_PREVIEW_FPS_RANGE,
2045 String8::format("%d,%d",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002046 k.mParameters.previewFpsRange[0],
2047 k.mParameters.previewFpsRange[1]));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002048
2049 {
2050 String8 supportedPreviewFpsRange;
2051 for (size_t i=0; i < availableFpsRanges.count; i += 2) {
2052 if (i != 0) supportedPreviewFpsRange += ",";
2053 supportedPreviewFpsRange += String8::format("(%d,%d)",
2054 availableFpsRanges.data.i32[i],
2055 availableFpsRanges.data.i32[i+1]);
2056 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002057 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002058 supportedPreviewFpsRange);
2059 }
2060
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002061 k.mParameters.previewFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002062 params.set(CameraParameters::KEY_PREVIEW_FORMAT,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002063 formatEnumToString(k.mParameters.previewFormat)); // NV21
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002064
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002065 k.mParameters.previewTransform = degToTransform(0,
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07002066 mCameraFacing == CAMERA_FACING_FRONT);
2067
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002068 camera_metadata_entry_t availableFormats =
2069 staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
2070
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002071 {
2072 String8 supportedPreviewFormats;
2073 bool addComma = false;
2074 for (size_t i=0; i < availableFormats.count; i++) {
2075 if (addComma) supportedPreviewFormats += ",";
2076 addComma = true;
2077 switch (availableFormats.data.i32[i]) {
2078 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002079 supportedPreviewFormats +=
2080 CameraParameters::PIXEL_FORMAT_YUV422SP;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002081 break;
2082 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002083 supportedPreviewFormats +=
2084 CameraParameters::PIXEL_FORMAT_YUV420SP;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002085 break;
2086 case HAL_PIXEL_FORMAT_YCbCr_422_I:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002087 supportedPreviewFormats +=
2088 CameraParameters::PIXEL_FORMAT_YUV422I;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002089 break;
2090 case HAL_PIXEL_FORMAT_YV12:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002091 supportedPreviewFormats +=
2092 CameraParameters::PIXEL_FORMAT_YUV420P;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002093 break;
2094 case HAL_PIXEL_FORMAT_RGB_565:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002095 supportedPreviewFormats +=
2096 CameraParameters::PIXEL_FORMAT_RGB565;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002097 break;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07002098 case HAL_PIXEL_FORMAT_RGBA_8888:
2099 supportedPreviewFormats +=
2100 CameraParameters::PIXEL_FORMAT_RGBA8888;
2101 break;
2102 // Not advertizing JPEG, RAW_SENSOR, etc, for preview formats
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002103 case HAL_PIXEL_FORMAT_RAW_SENSOR:
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07002104 case HAL_PIXEL_FORMAT_BLOB:
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002105 addComma = false;
2106 break;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07002107
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002108 default:
2109 ALOGW("%s: Camera %d: Unknown preview format: %x",
2110 __FUNCTION__, mCameraId, availableFormats.data.i32[i]);
2111 addComma = false;
2112 break;
2113 }
2114 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002115 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002116 supportedPreviewFormats);
2117 }
2118
2119 // PREVIEW_FRAME_RATE / SUPPORTED_PREVIEW_FRAME_RATES are deprecated, but
2120 // still have to do something sane for them
2121
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002122 params.set(CameraParameters::KEY_PREVIEW_FRAME_RATE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002123 k.mParameters.previewFpsRange[0]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002124
2125 {
2126 String8 supportedPreviewFrameRates;
2127 for (size_t i=0; i < availableFpsRanges.count; i += 2) {
2128 if (i != 0) supportedPreviewFrameRates += ",";
2129 supportedPreviewFrameRates += String8::format("%d",
2130 availableFpsRanges.data.i32[i]);
2131 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002132 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002133 supportedPreviewFrameRates);
2134 }
2135
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002136 camera_metadata_entry_t availableJpegSizes =
2137 staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES, 2);
2138 if (!availableJpegSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002139
2140 // TODO: Pick maximum
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002141 k.mParameters.pictureWidth = availableJpegSizes.data.i32[0];
2142 k.mParameters.pictureHeight = availableJpegSizes.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002143
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002144 params.setPictureSize(k.mParameters.pictureWidth,
2145 k.mParameters.pictureHeight);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002146
2147 {
2148 String8 supportedPictureSizes;
2149 for (size_t i=0; i < availableJpegSizes.count; i += 2) {
2150 if (i != 0) supportedPictureSizes += ",";
2151 supportedPictureSizes += String8::format("%dx%d",
2152 availableJpegSizes.data.i32[i],
2153 availableJpegSizes.data.i32[i+1]);
2154 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002155 params.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002156 supportedPictureSizes);
2157 }
2158
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002159 params.setPictureFormat(CameraParameters::PIXEL_FORMAT_JPEG);
2160 params.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS,
2161 CameraParameters::PIXEL_FORMAT_JPEG);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002162
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002163 camera_metadata_entry_t availableJpegThumbnailSizes =
2164 staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES, 2);
2165 if (!availableJpegThumbnailSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002166
2167 // TODO: Pick default thumbnail size sensibly
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002168 k.mParameters.jpegThumbSize[0] = availableJpegThumbnailSizes.data.i32[0];
2169 k.mParameters.jpegThumbSize[1] = availableJpegThumbnailSizes.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002170
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002171 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002172 k.mParameters.jpegThumbSize[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002173 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002174 k.mParameters.jpegThumbSize[1]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002175
2176 {
2177 String8 supportedJpegThumbSizes;
2178 for (size_t i=0; i < availableJpegThumbnailSizes.count; i += 2) {
2179 if (i != 0) supportedJpegThumbSizes += ",";
2180 supportedJpegThumbSizes += String8::format("%dx%d",
2181 availableJpegThumbnailSizes.data.i32[i],
2182 availableJpegThumbnailSizes.data.i32[i+1]);
2183 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002184 params.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002185 supportedJpegThumbSizes);
2186 }
2187
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002188 k.mParameters.jpegThumbQuality = 90;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002189 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002190 k.mParameters.jpegThumbQuality);
2191 k.mParameters.jpegQuality = 90;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002192 params.set(CameraParameters::KEY_JPEG_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002193 k.mParameters.jpegQuality);
2194 k.mParameters.jpegRotation = 0;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002195 params.set(CameraParameters::KEY_ROTATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002196 k.mParameters.jpegRotation);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002197
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002198 k.mParameters.gpsEnabled = false;
2199 k.mParameters.gpsProcessingMethod = "unknown";
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002200 // GPS fields in CameraParameters are not set by implementation
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002201
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002202 k.mParameters.wbMode = ANDROID_CONTROL_AWB_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002203 params.set(CameraParameters::KEY_WHITE_BALANCE,
2204 CameraParameters::WHITE_BALANCE_AUTO);
2205
2206 camera_metadata_entry_t availableWhiteBalanceModes =
2207 staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002208 {
2209 String8 supportedWhiteBalance;
2210 bool addComma = false;
2211 for (size_t i=0; i < availableWhiteBalanceModes.count; i++) {
2212 if (addComma) supportedWhiteBalance += ",";
2213 addComma = true;
2214 switch (availableWhiteBalanceModes.data.u8[i]) {
2215 case ANDROID_CONTROL_AWB_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002216 supportedWhiteBalance +=
2217 CameraParameters::WHITE_BALANCE_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002218 break;
2219 case ANDROID_CONTROL_AWB_INCANDESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002220 supportedWhiteBalance +=
2221 CameraParameters::WHITE_BALANCE_INCANDESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002222 break;
2223 case ANDROID_CONTROL_AWB_FLUORESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002224 supportedWhiteBalance +=
2225 CameraParameters::WHITE_BALANCE_FLUORESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002226 break;
2227 case ANDROID_CONTROL_AWB_WARM_FLUORESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002228 supportedWhiteBalance +=
2229 CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002230 break;
2231 case ANDROID_CONTROL_AWB_DAYLIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002232 supportedWhiteBalance +=
2233 CameraParameters::WHITE_BALANCE_DAYLIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002234 break;
2235 case ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002236 supportedWhiteBalance +=
2237 CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002238 break;
2239 case ANDROID_CONTROL_AWB_TWILIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002240 supportedWhiteBalance +=
2241 CameraParameters::WHITE_BALANCE_TWILIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002242 break;
2243 case ANDROID_CONTROL_AWB_SHADE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002244 supportedWhiteBalance +=
2245 CameraParameters::WHITE_BALANCE_SHADE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002246 break;
2247 // Skipping values not mappable to v1 API
2248 case ANDROID_CONTROL_AWB_OFF:
2249 addComma = false;
2250 break;
2251 default:
2252 ALOGW("%s: Camera %d: Unknown white balance value: %d",
2253 __FUNCTION__, mCameraId,
2254 availableWhiteBalanceModes.data.u8[i]);
2255 addComma = false;
2256 break;
2257 }
2258 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002259 params.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002260 supportedWhiteBalance);
2261 }
2262
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002263 k.mParameters.effectMode = ANDROID_CONTROL_EFFECT_OFF;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002264 params.set(CameraParameters::KEY_EFFECT,
2265 CameraParameters::EFFECT_NONE);
2266
2267 camera_metadata_entry_t availableEffects =
2268 staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
2269 if (!availableEffects.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002270 {
2271 String8 supportedEffects;
2272 bool addComma = false;
2273 for (size_t i=0; i < availableEffects.count; i++) {
2274 if (addComma) supportedEffects += ",";
2275 addComma = true;
2276 switch (availableEffects.data.u8[i]) {
2277 case ANDROID_CONTROL_EFFECT_OFF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002278 supportedEffects +=
2279 CameraParameters::EFFECT_NONE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002280 break;
2281 case ANDROID_CONTROL_EFFECT_MONO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002282 supportedEffects +=
2283 CameraParameters::EFFECT_MONO;
2284 break;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002285 case ANDROID_CONTROL_EFFECT_NEGATIVE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002286 supportedEffects +=
2287 CameraParameters::EFFECT_NEGATIVE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002288 break;
2289 case ANDROID_CONTROL_EFFECT_SOLARIZE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002290 supportedEffects +=
2291 CameraParameters::EFFECT_SOLARIZE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002292 break;
2293 case ANDROID_CONTROL_EFFECT_SEPIA:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002294 supportedEffects +=
2295 CameraParameters::EFFECT_SEPIA;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002296 break;
2297 case ANDROID_CONTROL_EFFECT_POSTERIZE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002298 supportedEffects +=
2299 CameraParameters::EFFECT_POSTERIZE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002300 break;
2301 case ANDROID_CONTROL_EFFECT_WHITEBOARD:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002302 supportedEffects +=
2303 CameraParameters::EFFECT_WHITEBOARD;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002304 break;
2305 case ANDROID_CONTROL_EFFECT_BLACKBOARD:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002306 supportedEffects +=
2307 CameraParameters::EFFECT_BLACKBOARD;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002308 break;
2309 case ANDROID_CONTROL_EFFECT_AQUA:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002310 supportedEffects +=
2311 CameraParameters::EFFECT_AQUA;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002312 break;
2313 default:
2314 ALOGW("%s: Camera %d: Unknown effect value: %d",
2315 __FUNCTION__, mCameraId, availableEffects.data.u8[i]);
2316 addComma = false;
2317 break;
2318 }
2319 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002320 params.set(CameraParameters::KEY_SUPPORTED_EFFECTS, supportedEffects);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002321 }
2322
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002323 k.mParameters.antibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002324 params.set(CameraParameters::KEY_ANTIBANDING,
2325 CameraParameters::ANTIBANDING_AUTO);
2326
2327 camera_metadata_entry_t availableAntibandingModes =
2328 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
2329 if (!availableAntibandingModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002330 {
2331 String8 supportedAntibanding;
2332 bool addComma = false;
2333 for (size_t i=0; i < availableAntibandingModes.count; i++) {
2334 if (addComma) supportedAntibanding += ",";
2335 addComma = true;
2336 switch (availableAntibandingModes.data.u8[i]) {
2337 case ANDROID_CONTROL_AE_ANTIBANDING_OFF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002338 supportedAntibanding +=
2339 CameraParameters::ANTIBANDING_OFF;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002340 break;
2341 case ANDROID_CONTROL_AE_ANTIBANDING_50HZ:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002342 supportedAntibanding +=
2343 CameraParameters::ANTIBANDING_50HZ;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002344 break;
2345 case ANDROID_CONTROL_AE_ANTIBANDING_60HZ:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002346 supportedAntibanding +=
2347 CameraParameters::ANTIBANDING_60HZ;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002348 break;
2349 case ANDROID_CONTROL_AE_ANTIBANDING_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002350 supportedAntibanding +=
2351 CameraParameters::ANTIBANDING_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002352 break;
2353 default:
2354 ALOGW("%s: Camera %d: Unknown antibanding value: %d",
2355 __FUNCTION__, mCameraId,
2356 availableAntibandingModes.data.u8[i]);
2357 addComma = false;
2358 break;
2359 }
2360 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002361 params.set(CameraParameters::KEY_SUPPORTED_ANTIBANDING,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002362 supportedAntibanding);
2363 }
2364
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002365 k.mParameters.sceneMode = ANDROID_CONTROL_OFF;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002366 params.set(CameraParameters::KEY_SCENE_MODE,
2367 CameraParameters::SCENE_MODE_AUTO);
2368
2369 camera_metadata_entry_t availableSceneModes =
2370 staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
2371 if (!availableSceneModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002372 {
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002373 String8 supportedSceneModes(CameraParameters::SCENE_MODE_AUTO);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002374 bool addComma = true;
2375 bool noSceneModes = false;
2376 for (size_t i=0; i < availableSceneModes.count; i++) {
2377 if (addComma) supportedSceneModes += ",";
2378 addComma = true;
2379 switch (availableSceneModes.data.u8[i]) {
2380 case ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED:
2381 noSceneModes = true;
2382 break;
2383 case ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY:
2384 // Not in old API
2385 addComma = false;
2386 break;
2387 case ANDROID_CONTROL_SCENE_MODE_ACTION:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002388 supportedSceneModes +=
2389 CameraParameters::SCENE_MODE_ACTION;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002390 break;
2391 case ANDROID_CONTROL_SCENE_MODE_PORTRAIT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002392 supportedSceneModes +=
2393 CameraParameters::SCENE_MODE_PORTRAIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002394 break;
2395 case ANDROID_CONTROL_SCENE_MODE_LANDSCAPE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002396 supportedSceneModes +=
2397 CameraParameters::SCENE_MODE_LANDSCAPE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002398 break;
2399 case ANDROID_CONTROL_SCENE_MODE_NIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002400 supportedSceneModes +=
2401 CameraParameters::SCENE_MODE_NIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002402 break;
2403 case ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002404 supportedSceneModes +=
2405 CameraParameters::SCENE_MODE_NIGHT_PORTRAIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002406 break;
2407 case ANDROID_CONTROL_SCENE_MODE_THEATRE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002408 supportedSceneModes +=
2409 CameraParameters::SCENE_MODE_THEATRE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002410 break;
2411 case ANDROID_CONTROL_SCENE_MODE_BEACH:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002412 supportedSceneModes +=
2413 CameraParameters::SCENE_MODE_BEACH;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002414 break;
2415 case ANDROID_CONTROL_SCENE_MODE_SNOW:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002416 supportedSceneModes +=
2417 CameraParameters::SCENE_MODE_SNOW;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002418 break;
2419 case ANDROID_CONTROL_SCENE_MODE_SUNSET:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002420 supportedSceneModes +=
2421 CameraParameters::SCENE_MODE_SUNSET;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002422 break;
2423 case ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002424 supportedSceneModes +=
2425 CameraParameters::SCENE_MODE_STEADYPHOTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002426 break;
2427 case ANDROID_CONTROL_SCENE_MODE_FIREWORKS:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002428 supportedSceneModes +=
2429 CameraParameters::SCENE_MODE_FIREWORKS;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002430 break;
2431 case ANDROID_CONTROL_SCENE_MODE_SPORTS:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002432 supportedSceneModes +=
2433 CameraParameters::SCENE_MODE_SPORTS;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002434 break;
2435 case ANDROID_CONTROL_SCENE_MODE_PARTY:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002436 supportedSceneModes +=
2437 CameraParameters::SCENE_MODE_PARTY;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002438 break;
2439 case ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002440 supportedSceneModes +=
2441 CameraParameters::SCENE_MODE_CANDLELIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002442 break;
2443 case ANDROID_CONTROL_SCENE_MODE_BARCODE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002444 supportedSceneModes +=
2445 CameraParameters::SCENE_MODE_BARCODE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002446 break;
2447 default:
2448 ALOGW("%s: Camera %d: Unknown scene mode value: %d",
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002449 __FUNCTION__, mCameraId,
2450 availableSceneModes.data.u8[i]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002451 addComma = false;
2452 break;
2453 }
2454 }
2455 if (!noSceneModes) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002456 params.set(CameraParameters::KEY_SUPPORTED_SCENE_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002457 supportedSceneModes);
2458 }
2459 }
2460
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002461 camera_metadata_entry_t flashAvailable =
2462 staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
2463 if (!flashAvailable.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002464
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002465 camera_metadata_entry_t availableAeModes =
2466 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
2467 if (!availableAeModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002468
2469 if (flashAvailable.data.u8[0]) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002470 k.mParameters.flashMode = Parameters::FLASH_MODE_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002471 params.set(CameraParameters::KEY_FLASH_MODE,
2472 CameraParameters::FLASH_MODE_AUTO);
2473
2474 String8 supportedFlashModes(CameraParameters::FLASH_MODE_OFF);
2475 supportedFlashModes = supportedFlashModes +
2476 "," + CameraParameters::FLASH_MODE_AUTO +
2477 "," + CameraParameters::FLASH_MODE_ON +
2478 "," + CameraParameters::FLASH_MODE_TORCH;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002479 for (size_t i=0; i < availableAeModes.count; i++) {
2480 if (availableAeModes.data.u8[i] ==
2481 ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002482 supportedFlashModes = supportedFlashModes + "," +
2483 CameraParameters::FLASH_MODE_RED_EYE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002484 break;
2485 }
2486 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002487 params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002488 supportedFlashModes);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002489 } else {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002490 k.mParameters.flashMode = Parameters::FLASH_MODE_OFF;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002491 params.set(CameraParameters::KEY_FLASH_MODE,
2492 CameraParameters::FLASH_MODE_OFF);
2493 params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
2494 CameraParameters::FLASH_MODE_OFF);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002495 }
2496
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002497 camera_metadata_entry_t minFocusDistance =
2498 staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE, 1, 1);
2499 if (!minFocusDistance.count) return NO_INIT;
2500
2501 camera_metadata_entry_t availableAfModes =
2502 staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
2503 if (!availableAfModes.count) return NO_INIT;
2504
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002505 if (minFocusDistance.data.f[0] == 0) {
2506 // Fixed-focus lens
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002507 k.mParameters.focusMode = Parameters::FOCUS_MODE_FIXED;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002508 params.set(CameraParameters::KEY_FOCUS_MODE,
2509 CameraParameters::FOCUS_MODE_FIXED);
2510 params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
2511 CameraParameters::FOCUS_MODE_FIXED);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002512 } else {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002513 k.mParameters.focusMode = Parameters::FOCUS_MODE_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002514 params.set(CameraParameters::KEY_FOCUS_MODE,
2515 CameraParameters::FOCUS_MODE_AUTO);
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07002516 String8 supportedFocusModes(CameraParameters::FOCUS_MODE_INFINITY);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002517 bool addComma = true;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002518
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002519 for (size_t i=0; i < availableAfModes.count; i++) {
2520 if (addComma) supportedFocusModes += ",";
2521 addComma = true;
2522 switch (availableAfModes.data.u8[i]) {
2523 case ANDROID_CONTROL_AF_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002524 supportedFocusModes +=
2525 CameraParameters::FOCUS_MODE_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002526 break;
2527 case ANDROID_CONTROL_AF_MACRO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002528 supportedFocusModes +=
2529 CameraParameters::FOCUS_MODE_MACRO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002530 break;
2531 case ANDROID_CONTROL_AF_CONTINUOUS_VIDEO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002532 supportedFocusModes +=
2533 CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002534 break;
2535 case ANDROID_CONTROL_AF_CONTINUOUS_PICTURE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002536 supportedFocusModes +=
2537 CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002538 break;
2539 case ANDROID_CONTROL_AF_EDOF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002540 supportedFocusModes +=
2541 CameraParameters::FOCUS_MODE_EDOF;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002542 break;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002543 // Not supported in old API
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002544 case ANDROID_CONTROL_AF_OFF:
2545 addComma = false;
2546 break;
2547 default:
2548 ALOGW("%s: Camera %d: Unknown AF mode value: %d",
2549 __FUNCTION__, mCameraId, availableAfModes.data.u8[i]);
2550 addComma = false;
2551 break;
2552 }
2553 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002554 params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002555 supportedFocusModes);
2556 }
2557
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002558 camera_metadata_entry_t max3aRegions =
2559 staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1);
2560 if (!max3aRegions.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002561
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002562 params.set(CameraParameters::KEY_MAX_NUM_FOCUS_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002563 max3aRegions.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002564 params.set(CameraParameters::KEY_FOCUS_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002565 "(0,0,0,0,0)");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002566 k.mParameters.focusingAreas.clear();
2567 k.mParameters.focusingAreas.add(Parameters::Area(0,0,0,0,0));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002568
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002569 camera_metadata_entry_t availableFocalLengths =
2570 staticInfo(ANDROID_LENS_AVAILABLE_FOCAL_LENGTHS);
2571 if (!availableFocalLengths.count) return NO_INIT;
2572
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002573 float minFocalLength = availableFocalLengths.data.f[0];
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002574 params.setFloat(CameraParameters::KEY_FOCAL_LENGTH, minFocalLength);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002575
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002576 camera_metadata_entry_t sensorSize =
2577 staticInfo(ANDROID_SENSOR_PHYSICAL_SIZE, 2, 2);
2578 if (!sensorSize.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002579
2580 // The fields of view here assume infinity focus, maximum wide angle
2581 float horizFov = 180 / M_PI *
2582 2 * atanf(sensorSize.data.f[0] / (2 * minFocalLength));
2583 float vertFov = 180 / M_PI *
2584 2 * atanf(sensorSize.data.f[1] / (2 * minFocalLength));
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002585 params.setFloat(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, horizFov);
2586 params.setFloat(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, vertFov);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002587
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002588 k.mParameters.exposureCompensation = 0;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002589 params.set(CameraParameters::KEY_EXPOSURE_COMPENSATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002590 k.mParameters.exposureCompensation);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002591
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002592 camera_metadata_entry_t exposureCompensationRange =
2593 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE, 2, 2);
2594 if (!exposureCompensationRange.count) return NO_INIT;
2595
2596 params.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002597 exposureCompensationRange.data.i32[1]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002598 params.set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002599 exposureCompensationRange.data.i32[0]);
2600
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002601 camera_metadata_entry_t exposureCompensationStep =
2602 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_STEP, 1, 1);
2603 if (!exposureCompensationStep.count) return NO_INIT;
2604
2605 params.setFloat(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP,
Eino-Ville Talvalad6f8e082012-08-02 16:00:35 -07002606 (float)exposureCompensationStep.data.r[0].numerator /
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002607 exposureCompensationStep.data.r[0].denominator);
2608
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002609 k.mParameters.autoExposureLock = false;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002610 params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK,
2611 CameraParameters::FALSE);
2612 params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED,
2613 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002614
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002615 k.mParameters.autoWhiteBalanceLock = false;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002616 params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK,
2617 CameraParameters::FALSE);
2618 params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED,
2619 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002620
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002621 k.mParameters.meteringAreas.add(Parameters::Area(0, 0, 0, 0, 0));
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002622 params.set(CameraParameters::KEY_MAX_NUM_METERING_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002623 max3aRegions.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002624 params.set(CameraParameters::KEY_METERING_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002625 "(0,0,0,0,0)");
2626
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002627 k.mParameters.zoom = 0;
2628 params.set(CameraParameters::KEY_ZOOM, k.mParameters.zoom);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002629 params.set(CameraParameters::KEY_MAX_ZOOM, NUM_ZOOM_STEPS - 1);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002630
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002631 camera_metadata_entry_t maxDigitalZoom =
2632 staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM, 1, 1);
2633 if (!maxDigitalZoom.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002634
2635 {
2636 String8 zoomRatios;
2637 float zoom = 1.f;
2638 float zoomIncrement = (maxDigitalZoom.data.f[0] - zoom) /
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002639 (NUM_ZOOM_STEPS-1);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002640 bool addComma = false;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002641 for (size_t i=0; i < NUM_ZOOM_STEPS; i++) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002642 if (addComma) zoomRatios += ",";
2643 addComma = true;
2644 zoomRatios += String8::format("%d", static_cast<int>(zoom * 100));
2645 zoom += zoomIncrement;
2646 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002647 params.set(CameraParameters::KEY_ZOOM_RATIOS, zoomRatios);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002648 }
2649
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002650 params.set(CameraParameters::KEY_ZOOM_SUPPORTED,
2651 CameraParameters::TRUE);
2652 params.set(CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED,
2653 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002654
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002655 params.set(CameraParameters::KEY_FOCUS_DISTANCES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002656 "Infinity,Infinity,Infinity");
2657
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002658 camera_metadata_entry_t maxFacesDetected =
2659 staticInfo(ANDROID_STATS_MAX_FACE_COUNT, 1, 1);
2660 params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002661 maxFacesDetected.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002662 params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002663 0);
2664
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002665 params.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT,
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002666 CameraParameters::PIXEL_FORMAT_ANDROID_OPAQUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002667
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002668 params.set(CameraParameters::KEY_RECORDING_HINT,
2669 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002670
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002671 params.set(CameraParameters::KEY_VIDEO_SNAPSHOT_SUPPORTED,
2672 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002673
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002674 params.set(CameraParameters::KEY_VIDEO_STABILIZATION,
2675 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002676
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002677 camera_metadata_entry_t availableVideoStabilizationModes =
2678 staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
2679 if (!availableVideoStabilizationModes.count) return NO_INIT;
2680
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002681 if (availableVideoStabilizationModes.count > 1) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002682 params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
2683 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002684 } else {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002685 params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
2686 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002687 }
2688
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07002689 // Set up initial state for non-Camera.Parameters state variables
2690
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002691 k.mParameters.storeMetadataInBuffers = true;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07002692 k.mParameters.playShutterSound = true;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07002693 k.mParameters.afTriggerCounter = 0;
2694 k.mParameters.currentAfTriggerId = -1;
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002695
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002696 k.mParameters.paramsFlattened = params.flatten();
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002697
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002698 return OK;
2699}
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07002700
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002701status_t Camera2Client::updatePreviewStream(const Parameters &params) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002702 ATRACE_CALL();
2703 status_t res;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002704
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002705 if (mPreviewStreamId != NO_STREAM) {
2706 // Check if stream parameters have to change
2707 uint32_t currentWidth, currentHeight;
2708 res = mDevice->getStreamInfo(mPreviewStreamId,
2709 &currentWidth, &currentHeight, 0);
2710 if (res != OK) {
2711 ALOGE("%s: Camera %d: Error querying preview stream info: "
2712 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2713 return res;
2714 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002715 if (currentWidth != (uint32_t)params.previewWidth ||
2716 currentHeight != (uint32_t)params.previewHeight) {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -07002717 ALOGV("%s: Camera %d: Preview size switch: %d x %d -> %d x %d",
2718 __FUNCTION__, mCameraId, currentWidth, currentHeight,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002719 params.previewWidth, params.previewHeight);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002720 res = mDevice->waitUntilDrained();
2721 if (res != OK) {
2722 ALOGE("%s: Camera %d: Error waiting for preview to drain: "
2723 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2724 return res;
2725 }
2726 res = mDevice->deleteStream(mPreviewStreamId);
2727 if (res != OK) {
2728 ALOGE("%s: Camera %d: Unable to delete old output stream "
2729 "for preview: %s (%d)", __FUNCTION__, mCameraId,
2730 strerror(-res), res);
2731 return res;
2732 }
2733 mPreviewStreamId = NO_STREAM;
2734 }
2735 }
2736
2737 if (mPreviewStreamId == NO_STREAM) {
2738 res = mDevice->createStream(mPreviewWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002739 params.previewWidth, params.previewHeight,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002740 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0,
2741 &mPreviewStreamId);
2742 if (res != OK) {
2743 ALOGE("%s: Camera %d: Unable to create preview stream: %s (%d)",
2744 __FUNCTION__, mCameraId, strerror(-res), res);
2745 return res;
2746 }
2747 }
2748
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07002749 res = mDevice->setStreamTransform(mPreviewStreamId,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002750 params.previewTransform);
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07002751 if (res != OK) {
2752 ALOGE("%s: Camera %d: Unable to set preview stream transform: "
2753 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2754 return res;
2755 }
2756
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002757 return OK;
2758}
2759
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002760status_t Camera2Client::updatePreviewRequest(const Parameters &params) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07002761 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002762 status_t res;
2763 if (mPreviewRequest == NULL) {
2764 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
2765 &mPreviewRequest);
2766 if (res != OK) {
2767 ALOGE("%s: Camera %d: Unable to create default preview request: "
2768 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2769 return res;
2770 }
2771 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002772
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002773 res = updateRequestCommon(mPreviewRequest, params);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002774 if (res != OK) {
2775 ALOGE("%s: Camera %d: Unable to update common entries of preview "
2776 "request: %s (%d)", __FUNCTION__, mCameraId,
2777 strerror(-res), res);
2778 return res;
2779 }
2780
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002781 return OK;
2782}
2783
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002784status_t Camera2Client::updateCaptureStream(const Parameters &params) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002785 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002786 status_t res;
2787 // Find out buffer size for JPEG
2788 camera_metadata_entry_t maxJpegSize =
2789 staticInfo(ANDROID_JPEG_MAX_SIZE);
2790 if (maxJpegSize.count == 0) {
2791 ALOGE("%s: Camera %d: Can't find ANDROID_JPEG_MAX_SIZE!",
2792 __FUNCTION__, mCameraId);
2793 return INVALID_OPERATION;
2794 }
2795
2796 if (mCaptureConsumer == 0) {
2797 // Create CPU buffer queue endpoint
2798 mCaptureConsumer = new CpuConsumer(1);
2799 mCaptureConsumer->setFrameAvailableListener(new CaptureWaiter(this));
2800 mCaptureConsumer->setName(String8("Camera2Client::CaptureConsumer"));
2801 mCaptureWindow = new SurfaceTextureClient(
2802 mCaptureConsumer->getProducerInterface());
2803 // Create memory for API consumption
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002804 mCaptureHeap = new Camera2Heap(maxJpegSize.data.i32[0], 1,
2805 "Camera2Client::CaptureHeap");
2806 if (mCaptureHeap->mHeap->getSize() == 0) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002807 ALOGE("%s: Camera %d: Unable to allocate memory for capture",
2808 __FUNCTION__, mCameraId);
2809 return NO_MEMORY;
2810 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002811 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002812
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002813 if (mCaptureStreamId != NO_STREAM) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002814 // Check if stream parameters have to change
2815 uint32_t currentWidth, currentHeight;
2816 res = mDevice->getStreamInfo(mCaptureStreamId,
2817 &currentWidth, &currentHeight, 0);
2818 if (res != OK) {
2819 ALOGE("%s: Camera %d: Error querying capture output stream info: "
2820 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2821 return res;
2822 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002823 if (currentWidth != (uint32_t)params.pictureWidth ||
2824 currentHeight != (uint32_t)params.pictureHeight) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002825 res = mDevice->deleteStream(mCaptureStreamId);
2826 if (res != OK) {
2827 ALOGE("%s: Camera %d: Unable to delete old output stream "
2828 "for capture: %s (%d)", __FUNCTION__, mCameraId,
2829 strerror(-res), res);
2830 return res;
2831 }
2832 mCaptureStreamId = NO_STREAM;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002833 }
2834 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002835
2836 if (mCaptureStreamId == NO_STREAM) {
2837 // Create stream for HAL production
2838 res = mDevice->createStream(mCaptureWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002839 params.pictureWidth, params.pictureHeight,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002840 HAL_PIXEL_FORMAT_BLOB, maxJpegSize.data.i32[0],
2841 &mCaptureStreamId);
2842 if (res != OK) {
2843 ALOGE("%s: Camera %d: Can't create output stream for capture: "
2844 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2845 return res;
2846 }
2847
2848 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002849 return OK;
2850}
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002851
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002852status_t Camera2Client::updateCaptureRequest(const Parameters &params) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002853 ATRACE_CALL();
2854 status_t res;
2855 if (mCaptureRequest == NULL) {
2856 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_STILL_CAPTURE,
2857 &mCaptureRequest);
2858 if (res != OK) {
2859 ALOGE("%s: Camera %d: Unable to create default still image request:"
2860 " %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2861 return res;
2862 }
2863 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002864
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002865 res = updateRequestCommon(mCaptureRequest, params);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002866 if (res != OK) {
2867 ALOGE("%s: Camera %d: Unable to update common entries of capture "
2868 "request: %s (%d)", __FUNCTION__, mCameraId,
2869 strerror(-res), res);
2870 return res;
2871 }
2872
2873 res = updateEntry(mCaptureRequest,
2874 ANDROID_JPEG_THUMBNAIL_SIZE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002875 params.jpegThumbSize, 2);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002876 if (res != OK) return res;
2877 res = updateEntry(mCaptureRequest,
2878 ANDROID_JPEG_THUMBNAIL_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002879 &params.jpegThumbQuality, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002880 if (res != OK) return res;
2881 res = updateEntry(mCaptureRequest,
2882 ANDROID_JPEG_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002883 &params.jpegQuality, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002884 if (res != OK) return res;
2885 res = updateEntry(mCaptureRequest,
2886 ANDROID_JPEG_ORIENTATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002887 &params.jpegRotation, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002888 if (res != OK) return res;
2889
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002890 if (params.gpsEnabled) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002891 res = updateEntry(mCaptureRequest,
2892 ANDROID_JPEG_GPS_COORDINATES,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002893 params.gpsCoordinates, 3);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002894 if (res != OK) return res;
2895 res = updateEntry(mCaptureRequest,
2896 ANDROID_JPEG_GPS_TIMESTAMP,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002897 &params.gpsTimestamp, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002898 if (res != OK) return res;
2899 res = updateEntry(mCaptureRequest,
2900 ANDROID_JPEG_GPS_PROCESSING_METHOD,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002901 params.gpsProcessingMethod.string(),
2902 params.gpsProcessingMethod.size());
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002903 if (res != OK) return res;
2904 } else {
2905 res = deleteEntry(mCaptureRequest,
2906 ANDROID_JPEG_GPS_COORDINATES);
2907 if (res != OK) return res;
2908 res = deleteEntry(mCaptureRequest,
2909 ANDROID_JPEG_GPS_TIMESTAMP);
2910 if (res != OK) return res;
2911 res = deleteEntry(mCaptureRequest,
2912 ANDROID_JPEG_GPS_PROCESSING_METHOD);
2913 if (res != OK) return res;
2914 }
2915
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002916 return OK;
2917}
2918
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002919status_t Camera2Client::updateRecordingRequest(const Parameters &params) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002920 ATRACE_CALL();
2921 status_t res;
2922 if (mRecordingRequest == NULL) {
2923 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_VIDEO_RECORD,
2924 &mRecordingRequest);
2925 if (res != OK) {
2926 ALOGE("%s: Camera %d: Unable to create default recording request:"
2927 " %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2928 return res;
2929 }
2930 }
2931
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002932 res = updateRequestCommon(mRecordingRequest, params);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002933 if (res != OK) {
2934 ALOGE("%s: Camera %d: Unable to update common entries of recording "
2935 "request: %s (%d)", __FUNCTION__, mCameraId,
2936 strerror(-res), res);
2937 return res;
2938 }
2939
2940 return OK;
2941}
2942
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002943status_t Camera2Client::updateRecordingStream(const Parameters &params) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002944 status_t res;
2945
2946 if (mRecordingConsumer == 0) {
2947 // Create CPU buffer queue endpoint
James Dong983cf232012-08-01 16:39:55 -07002948 mRecordingConsumer = new MediaConsumer(mRecordingHeapCount);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002949 mRecordingConsumer->setFrameAvailableListener(new RecordingWaiter(this));
2950 mRecordingConsumer->setName(String8("Camera2Client::RecordingConsumer"));
2951 mRecordingWindow = new SurfaceTextureClient(
2952 mRecordingConsumer->getProducerInterface());
2953 // Allocate memory later, since we don't know buffer size until receipt
2954 }
2955
2956 if (mRecordingStreamId != NO_STREAM) {
2957 // Check if stream parameters have to change
2958 uint32_t currentWidth, currentHeight;
2959 res = mDevice->getStreamInfo(mRecordingStreamId,
2960 &currentWidth, &currentHeight, 0);
2961 if (res != OK) {
2962 ALOGE("%s: Camera %d: Error querying recording output stream info: "
2963 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2964 return res;
2965 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002966 if (currentWidth != (uint32_t)params.videoWidth ||
2967 currentHeight != (uint32_t)params.videoHeight) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002968 // TODO: Should wait to be sure previous recording has finished
2969 res = mDevice->deleteStream(mRecordingStreamId);
2970 if (res != OK) {
2971 ALOGE("%s: Camera %d: Unable to delete old output stream "
2972 "for recording: %s (%d)", __FUNCTION__, mCameraId,
2973 strerror(-res), res);
2974 return res;
2975 }
2976 mRecordingStreamId = NO_STREAM;
2977 }
2978 }
2979
2980 if (mRecordingStreamId == NO_STREAM) {
2981 res = mDevice->createStream(mRecordingWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002982 params.videoWidth, params.videoHeight,
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002983 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0, &mRecordingStreamId);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002984 if (res != OK) {
2985 ALOGE("%s: Camera %d: Can't create output stream for recording: "
2986 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2987 return res;
2988 }
2989 }
2990
2991 return OK;
2992}
2993
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002994status_t Camera2Client::updateRequestCommon(camera_metadata_t *request,
2995 const Parameters &params) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002996 ATRACE_CALL();
2997 status_t res;
2998 res = updateEntry(request,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002999 ANDROID_CONTROL_AE_TARGET_FPS_RANGE, params.previewFpsRange, 2);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003000 if (res != OK) return res;
3001
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003002 uint8_t wbMode = params.autoWhiteBalanceLock ?
3003 ANDROID_CONTROL_AWB_LOCKED : params.wbMode;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003004 res = updateEntry(request,
3005 ANDROID_CONTROL_AWB_MODE, &wbMode, 1);
3006 if (res != OK) return res;
3007 res = updateEntry(request,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003008 ANDROID_CONTROL_EFFECT_MODE, &params.effectMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003009 if (res != OK) return res;
3010 res = updateEntry(request,
3011 ANDROID_CONTROL_AE_ANTIBANDING_MODE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003012 &params.antibandingMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003013 if (res != OK) return res;
3014
3015 uint8_t controlMode =
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003016 (params.sceneMode == ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED) ?
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003017 ANDROID_CONTROL_AUTO : ANDROID_CONTROL_USE_SCENE_MODE;
3018 res = updateEntry(request,
3019 ANDROID_CONTROL_MODE, &controlMode, 1);
3020 if (res != OK) return res;
3021 if (controlMode == ANDROID_CONTROL_USE_SCENE_MODE) {
3022 res = updateEntry(request,
3023 ANDROID_CONTROL_SCENE_MODE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003024 &params.sceneMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003025 if (res != OK) return res;
3026 }
3027
3028 uint8_t flashMode = ANDROID_FLASH_OFF;
3029 uint8_t aeMode;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003030 switch (params.flashMode) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003031 case Parameters::FLASH_MODE_OFF:
3032 aeMode = ANDROID_CONTROL_AE_ON; break;
3033 case Parameters::FLASH_MODE_AUTO:
3034 aeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH; break;
3035 case Parameters::FLASH_MODE_ON:
3036 aeMode = ANDROID_CONTROL_AE_ON_ALWAYS_FLASH; break;
3037 case Parameters::FLASH_MODE_TORCH:
3038 aeMode = ANDROID_CONTROL_AE_ON;
3039 flashMode = ANDROID_FLASH_TORCH;
3040 break;
3041 case Parameters::FLASH_MODE_RED_EYE:
3042 aeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE; break;
3043 default:
3044 ALOGE("%s: Camera %d: Unknown flash mode %d", __FUNCTION__,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003045 mCameraId, params.flashMode);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003046 return BAD_VALUE;
3047 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003048 if (params.autoExposureLock) aeMode = ANDROID_CONTROL_AE_LOCKED;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003049
3050 res = updateEntry(request,
3051 ANDROID_FLASH_MODE, &flashMode, 1);
3052 if (res != OK) return res;
3053 res = updateEntry(request,
3054 ANDROID_CONTROL_AE_MODE, &aeMode, 1);
3055 if (res != OK) return res;
3056
3057 float focusDistance = 0; // infinity focus in diopters
3058 uint8_t focusMode;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003059 switch (params.focusMode) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003060 case Parameters::FOCUS_MODE_AUTO:
3061 case Parameters::FOCUS_MODE_MACRO:
3062 case Parameters::FOCUS_MODE_CONTINUOUS_VIDEO:
3063 case Parameters::FOCUS_MODE_CONTINUOUS_PICTURE:
3064 case Parameters::FOCUS_MODE_EDOF:
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003065 focusMode = params.focusMode;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003066 break;
3067 case Parameters::FOCUS_MODE_INFINITY:
3068 case Parameters::FOCUS_MODE_FIXED:
3069 focusMode = ANDROID_CONTROL_AF_OFF;
3070 break;
3071 default:
3072 ALOGE("%s: Camera %d: Unknown focus mode %d", __FUNCTION__,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003073 mCameraId, params.focusMode);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003074 return BAD_VALUE;
3075 }
3076 res = updateEntry(request,
3077 ANDROID_LENS_FOCUS_DISTANCE, &focusDistance, 1);
3078 if (res != OK) return res;
3079 res = updateEntry(request,
3080 ANDROID_CONTROL_AF_MODE, &focusMode, 1);
3081 if (res != OK) return res;
3082
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003083 size_t focusingAreasSize = params.focusingAreas.size() * 5;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003084 int32_t *focusingAreas = new int32_t[focusingAreasSize];
3085 for (size_t i = 0; i < focusingAreasSize; i += 5) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003086 focusingAreas[i + 0] = params.focusingAreas[i].left;
3087 focusingAreas[i + 1] = params.focusingAreas[i].top;
3088 focusingAreas[i + 2] = params.focusingAreas[i].right;
3089 focusingAreas[i + 3] = params.focusingAreas[i].bottom;
3090 focusingAreas[i + 4] = params.focusingAreas[i].weight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003091 }
3092 res = updateEntry(request,
3093 ANDROID_CONTROL_AF_REGIONS, focusingAreas,focusingAreasSize);
3094 if (res != OK) return res;
3095 delete[] focusingAreas;
3096
3097 res = updateEntry(request,
3098 ANDROID_CONTROL_AE_EXP_COMPENSATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003099 &params.exposureCompensation, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003100 if (res != OK) return res;
3101
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003102 size_t meteringAreasSize = params.meteringAreas.size() * 5;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003103 int32_t *meteringAreas = new int32_t[meteringAreasSize];
3104 for (size_t i = 0; i < meteringAreasSize; i += 5) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003105 meteringAreas[i + 0] = params.meteringAreas[i].left;
3106 meteringAreas[i + 1] = params.meteringAreas[i].top;
3107 meteringAreas[i + 2] = params.meteringAreas[i].right;
3108 meteringAreas[i + 3] = params.meteringAreas[i].bottom;
3109 meteringAreas[i + 4] = params.meteringAreas[i].weight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003110 }
3111 res = updateEntry(request,
3112 ANDROID_CONTROL_AE_REGIONS, meteringAreas, meteringAreasSize);
3113 if (res != OK) return res;
3114
3115 res = updateEntry(request,
3116 ANDROID_CONTROL_AWB_REGIONS, meteringAreas, meteringAreasSize);
3117 if (res != OK) return res;
3118 delete[] meteringAreas;
3119
3120 // Need to convert zoom index into a crop rectangle. The rectangle is
3121 // chosen to maximize its area on the sensor
3122
3123 camera_metadata_entry_t maxDigitalZoom =
3124 staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM);
3125 float zoomIncrement = (maxDigitalZoom.data.f[0] - 1) /
3126 (NUM_ZOOM_STEPS-1);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003127 float zoomRatio = 1 + zoomIncrement * params.zoom;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003128
3129 camera_metadata_entry_t activePixelArraySize =
3130 staticInfo(ANDROID_SENSOR_ACTIVE_ARRAY_SIZE, 2, 2);
3131 int32_t arrayWidth = activePixelArraySize.data.i32[0];
3132 int32_t arrayHeight = activePixelArraySize.data.i32[1];
3133 float zoomLeft, zoomTop, zoomWidth, zoomHeight;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003134 if (params.previewWidth >= params.previewHeight) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003135 zoomWidth = arrayWidth / zoomRatio;
3136 zoomHeight = zoomWidth *
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003137 params.previewHeight / params.previewWidth;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003138 } else {
3139 zoomHeight = arrayHeight / zoomRatio;
3140 zoomWidth = zoomHeight *
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003141 params.previewWidth / params.previewHeight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003142 }
3143 zoomLeft = (arrayWidth - zoomWidth) / 2;
3144 zoomTop = (arrayHeight - zoomHeight) / 2;
3145
3146 int32_t cropRegion[3] = { zoomLeft, zoomTop, zoomWidth };
3147 res = updateEntry(request,
3148 ANDROID_SCALER_CROP_REGION, cropRegion, 3);
3149 if (res != OK) return res;
3150
3151 // TODO: Decide how to map recordingHint, or whether just to ignore it
3152
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003153 uint8_t vstabMode = params.videoStabilization ?
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003154 ANDROID_CONTROL_VIDEO_STABILIZATION_ON :
3155 ANDROID_CONTROL_VIDEO_STABILIZATION_OFF;
3156 res = updateEntry(request,
3157 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
3158 &vstabMode, 1);
3159 if (res != OK) return res;
3160
3161 return OK;
3162}
3163
3164status_t Camera2Client::updateEntry(camera_metadata_t *buffer,
3165 uint32_t tag, const void *data, size_t data_count) {
3166 camera_metadata_entry_t entry;
3167 status_t res;
3168 res = find_camera_metadata_entry(buffer, tag, &entry);
3169 if (res == NAME_NOT_FOUND) {
3170 res = add_camera_metadata_entry(buffer,
3171 tag, data, data_count);
3172 } else if (res == OK) {
3173 res = update_camera_metadata_entry(buffer,
3174 entry.index, data, data_count, NULL);
3175 }
3176
3177 if (res != OK) {
3178 ALOGE("%s: Unable to update metadata entry %s.%s (%x): %s (%d)",
3179 __FUNCTION__, get_camera_metadata_section_name(tag),
3180 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
3181 }
3182 return res;
3183}
3184
3185status_t Camera2Client::deleteEntry(camera_metadata_t *buffer, uint32_t tag) {
3186 camera_metadata_entry_t entry;
3187 status_t res;
3188 res = find_camera_metadata_entry(buffer, tag, &entry);
3189 if (res == NAME_NOT_FOUND) {
3190 return OK;
3191 } else if (res != OK) {
3192 ALOGE("%s: Error looking for entry %s.%s (%x): %s %d",
3193 __FUNCTION__,
3194 get_camera_metadata_section_name(tag),
3195 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
3196 return res;
3197 }
3198 res = delete_camera_metadata_entry(buffer, entry.index);
3199 if (res != OK) {
3200 ALOGE("%s: Error deleting entry %s.%s (%x): %s %d",
3201 __FUNCTION__,
3202 get_camera_metadata_section_name(tag),
3203 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
3204 }
3205 return res;
3206}
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003207
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07003208int Camera2Client::formatStringToEnum(const char *format) {
3209 return
3210 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422SP) ?
3211 HAL_PIXEL_FORMAT_YCbCr_422_SP : // NV16
3212 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420SP) ?
3213 HAL_PIXEL_FORMAT_YCrCb_420_SP : // NV21
3214 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422I) ?
3215 HAL_PIXEL_FORMAT_YCbCr_422_I : // YUY2
3216 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420P) ?
3217 HAL_PIXEL_FORMAT_YV12 : // YV12
3218 !strcmp(format, CameraParameters::PIXEL_FORMAT_RGB565) ?
3219 HAL_PIXEL_FORMAT_RGB_565 : // RGB565
3220 !strcmp(format, CameraParameters::PIXEL_FORMAT_RGBA8888) ?
3221 HAL_PIXEL_FORMAT_RGBA_8888 : // RGB8888
3222 !strcmp(format, CameraParameters::PIXEL_FORMAT_BAYER_RGGB) ?
3223 HAL_PIXEL_FORMAT_RAW_SENSOR : // Raw sensor data
3224 -1;
3225}
3226
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003227const char* Camera2Client::formatEnumToString(int format) {
3228 const char *fmt;
3229 switch(format) {
3230 case HAL_PIXEL_FORMAT_YCbCr_422_SP: // NV16
3231 fmt = CameraParameters::PIXEL_FORMAT_YUV422SP;
3232 break;
3233 case HAL_PIXEL_FORMAT_YCrCb_420_SP: // NV21
3234 fmt = CameraParameters::PIXEL_FORMAT_YUV420SP;
3235 break;
3236 case HAL_PIXEL_FORMAT_YCbCr_422_I: // YUY2
3237 fmt = CameraParameters::PIXEL_FORMAT_YUV422I;
3238 break;
3239 case HAL_PIXEL_FORMAT_YV12: // YV12
3240 fmt = CameraParameters::PIXEL_FORMAT_YUV420P;
3241 break;
3242 case HAL_PIXEL_FORMAT_RGB_565: // RGB565
3243 fmt = CameraParameters::PIXEL_FORMAT_RGB565;
3244 break;
3245 case HAL_PIXEL_FORMAT_RGBA_8888: // RGBA8888
3246 fmt = CameraParameters::PIXEL_FORMAT_RGBA8888;
3247 break;
3248 case HAL_PIXEL_FORMAT_RAW_SENSOR:
3249 ALOGW("Raw sensor preview format requested.");
3250 fmt = CameraParameters::PIXEL_FORMAT_BAYER_RGGB;
3251 break;
3252 default:
3253 ALOGE("%s: Unknown preview format: %x",
3254 __FUNCTION__, format);
3255 fmt = NULL;
3256 break;
3257 }
3258 return fmt;
3259}
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07003260
3261int Camera2Client::wbModeStringToEnum(const char *wbMode) {
3262 return
3263 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_AUTO) ?
3264 ANDROID_CONTROL_AWB_AUTO :
3265 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_INCANDESCENT) ?
3266 ANDROID_CONTROL_AWB_INCANDESCENT :
3267 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_FLUORESCENT) ?
3268 ANDROID_CONTROL_AWB_FLUORESCENT :
3269 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT) ?
3270 ANDROID_CONTROL_AWB_WARM_FLUORESCENT :
3271 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_DAYLIGHT) ?
3272 ANDROID_CONTROL_AWB_DAYLIGHT :
3273 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT) ?
3274 ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT :
3275 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_TWILIGHT) ?
3276 ANDROID_CONTROL_AWB_TWILIGHT :
3277 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_SHADE) ?
3278 ANDROID_CONTROL_AWB_SHADE :
3279 -1;
3280}
3281
3282int Camera2Client::effectModeStringToEnum(const char *effectMode) {
3283 return
3284 !strcmp(effectMode, CameraParameters::EFFECT_NONE) ?
3285 ANDROID_CONTROL_EFFECT_OFF :
3286 !strcmp(effectMode, CameraParameters::EFFECT_MONO) ?
3287 ANDROID_CONTROL_EFFECT_MONO :
3288 !strcmp(effectMode, CameraParameters::EFFECT_NEGATIVE) ?
3289 ANDROID_CONTROL_EFFECT_NEGATIVE :
3290 !strcmp(effectMode, CameraParameters::EFFECT_SOLARIZE) ?
3291 ANDROID_CONTROL_EFFECT_SOLARIZE :
3292 !strcmp(effectMode, CameraParameters::EFFECT_SEPIA) ?
3293 ANDROID_CONTROL_EFFECT_SEPIA :
3294 !strcmp(effectMode, CameraParameters::EFFECT_POSTERIZE) ?
3295 ANDROID_CONTROL_EFFECT_POSTERIZE :
3296 !strcmp(effectMode, CameraParameters::EFFECT_WHITEBOARD) ?
3297 ANDROID_CONTROL_EFFECT_WHITEBOARD :
3298 !strcmp(effectMode, CameraParameters::EFFECT_BLACKBOARD) ?
3299 ANDROID_CONTROL_EFFECT_BLACKBOARD :
3300 !strcmp(effectMode, CameraParameters::EFFECT_AQUA) ?
3301 ANDROID_CONTROL_EFFECT_AQUA :
3302 -1;
3303}
3304
3305int Camera2Client::abModeStringToEnum(const char *abMode) {
3306 return
3307 !strcmp(abMode, CameraParameters::ANTIBANDING_AUTO) ?
3308 ANDROID_CONTROL_AE_ANTIBANDING_AUTO :
3309 !strcmp(abMode, CameraParameters::ANTIBANDING_OFF) ?
3310 ANDROID_CONTROL_AE_ANTIBANDING_OFF :
3311 !strcmp(abMode, CameraParameters::ANTIBANDING_50HZ) ?
3312 ANDROID_CONTROL_AE_ANTIBANDING_50HZ :
3313 !strcmp(abMode, CameraParameters::ANTIBANDING_60HZ) ?
3314 ANDROID_CONTROL_AE_ANTIBANDING_60HZ :
3315 -1;
3316}
3317
3318int Camera2Client::sceneModeStringToEnum(const char *sceneMode) {
3319 return
3320 !strcmp(sceneMode, CameraParameters::SCENE_MODE_AUTO) ?
3321 ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED :
3322 !strcmp(sceneMode, CameraParameters::SCENE_MODE_ACTION) ?
3323 ANDROID_CONTROL_SCENE_MODE_ACTION :
3324 !strcmp(sceneMode, CameraParameters::SCENE_MODE_PORTRAIT) ?
3325 ANDROID_CONTROL_SCENE_MODE_PORTRAIT :
3326 !strcmp(sceneMode, CameraParameters::SCENE_MODE_LANDSCAPE) ?
3327 ANDROID_CONTROL_SCENE_MODE_LANDSCAPE :
3328 !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT) ?
3329 ANDROID_CONTROL_SCENE_MODE_NIGHT :
3330 !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT_PORTRAIT) ?
3331 ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT :
3332 !strcmp(sceneMode, CameraParameters::SCENE_MODE_THEATRE) ?
3333 ANDROID_CONTROL_SCENE_MODE_THEATRE :
3334 !strcmp(sceneMode, CameraParameters::SCENE_MODE_BEACH) ?
3335 ANDROID_CONTROL_SCENE_MODE_BEACH :
3336 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SNOW) ?
3337 ANDROID_CONTROL_SCENE_MODE_SNOW :
3338 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SUNSET) ?
3339 ANDROID_CONTROL_SCENE_MODE_SUNSET :
3340 !strcmp(sceneMode, CameraParameters::SCENE_MODE_STEADYPHOTO) ?
3341 ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO :
3342 !strcmp(sceneMode, CameraParameters::SCENE_MODE_FIREWORKS) ?
3343 ANDROID_CONTROL_SCENE_MODE_FIREWORKS :
3344 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SPORTS) ?
3345 ANDROID_CONTROL_SCENE_MODE_SPORTS :
3346 !strcmp(sceneMode, CameraParameters::SCENE_MODE_PARTY) ?
3347 ANDROID_CONTROL_SCENE_MODE_PARTY :
3348 !strcmp(sceneMode, CameraParameters::SCENE_MODE_CANDLELIGHT) ?
3349 ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT :
3350 !strcmp(sceneMode, CameraParameters::SCENE_MODE_BARCODE) ?
3351 ANDROID_CONTROL_SCENE_MODE_BARCODE:
3352 -1;
3353}
3354
3355Camera2Client::Parameters::flashMode_t Camera2Client::flashModeStringToEnum(
3356 const char *flashMode) {
3357 return
3358 !strcmp(flashMode, CameraParameters::FLASH_MODE_OFF) ?
3359 Parameters::FLASH_MODE_OFF :
3360 !strcmp(flashMode, CameraParameters::FLASH_MODE_AUTO) ?
3361 Parameters::FLASH_MODE_AUTO :
3362 !strcmp(flashMode, CameraParameters::FLASH_MODE_ON) ?
3363 Parameters::FLASH_MODE_ON :
3364 !strcmp(flashMode, CameraParameters::FLASH_MODE_RED_EYE) ?
3365 Parameters::FLASH_MODE_RED_EYE :
3366 !strcmp(flashMode, CameraParameters::FLASH_MODE_TORCH) ?
3367 Parameters::FLASH_MODE_TORCH :
3368 Parameters::FLASH_MODE_INVALID;
3369}
3370
3371Camera2Client::Parameters::focusMode_t Camera2Client::focusModeStringToEnum(
3372 const char *focusMode) {
3373 return
3374 !strcmp(focusMode, CameraParameters::FOCUS_MODE_AUTO) ?
3375 Parameters::FOCUS_MODE_AUTO :
3376 !strcmp(focusMode, CameraParameters::FOCUS_MODE_INFINITY) ?
3377 Parameters::FOCUS_MODE_INFINITY :
3378 !strcmp(focusMode, CameraParameters::FOCUS_MODE_MACRO) ?
3379 Parameters::FOCUS_MODE_MACRO :
3380 !strcmp(focusMode, CameraParameters::FOCUS_MODE_FIXED) ?
3381 Parameters::FOCUS_MODE_FIXED :
3382 !strcmp(focusMode, CameraParameters::FOCUS_MODE_EDOF) ?
3383 Parameters::FOCUS_MODE_EDOF :
3384 !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO) ?
3385 Parameters::FOCUS_MODE_CONTINUOUS_VIDEO :
3386 !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE) ?
3387 Parameters::FOCUS_MODE_CONTINUOUS_PICTURE :
3388 Parameters::FOCUS_MODE_INVALID;
3389}
3390
3391status_t Camera2Client::parseAreas(const char *areasCStr,
3392 Vector<Parameters::Area> *areas) {
3393 static const size_t NUM_FIELDS = 5;
3394 areas->clear();
3395 if (areasCStr == NULL) {
3396 // If no key exists, use default (0,0,0,0,0)
3397 areas->push();
3398 return OK;
3399 }
3400 String8 areasStr(areasCStr);
3401 ssize_t areaStart = areasStr.find("(", 0) + 1;
3402 while (areaStart != 0) {
3403 const char* area = areasStr.string() + areaStart;
3404 char *numEnd;
3405 int vals[NUM_FIELDS];
3406 for (size_t i = 0; i < NUM_FIELDS; i++) {
3407 errno = 0;
3408 vals[i] = strtol(area, &numEnd, 10);
3409 if (errno || numEnd == area) return BAD_VALUE;
3410 area = numEnd + 1;
3411 }
3412 areas->push(Parameters::Area(
3413 vals[0], vals[1], vals[2], vals[3], vals[4]) );
3414 areaStart = areasStr.find("(", areaStart) + 1;
3415 }
3416 return OK;
3417}
3418
3419status_t Camera2Client::validateAreas(const Vector<Parameters::Area> &areas,
3420 size_t maxRegions) {
3421 // Definition of valid area can be found in
3422 // include/camera/CameraParameters.h
3423 if (areas.size() == 0) return BAD_VALUE;
3424 if (areas.size() == 1) {
3425 if (areas[0].left == 0 &&
3426 areas[0].top == 0 &&
3427 areas[0].right == 0 &&
3428 areas[0].bottom == 0 &&
3429 areas[0].weight == 0) {
3430 // Single (0,0,0,0,0) entry is always valid (== driver decides)
3431 return OK;
3432 }
3433 }
3434 if (areas.size() > maxRegions) {
3435 ALOGE("%s: Too many areas requested: %d",
3436 __FUNCTION__, areas.size());
3437 return BAD_VALUE;
3438 }
3439
3440 for (Vector<Parameters::Area>::const_iterator a = areas.begin();
3441 a != areas.end(); a++) {
3442 if (a->weight < 1 || a->weight > 1000) return BAD_VALUE;
3443 if (a->left < -1000 || a->left > 1000) return BAD_VALUE;
3444 if (a->top < -1000 || a->top > 1000) return BAD_VALUE;
3445 if (a->right < -1000 || a->right > 1000) return BAD_VALUE;
3446 if (a->bottom < -1000 || a->bottom > 1000) return BAD_VALUE;
3447 if (a->left >= a->right) return BAD_VALUE;
3448 if (a->top >= a->bottom) return BAD_VALUE;
3449 }
3450 return OK;
3451}
3452
3453bool Camera2Client::boolFromString(const char *boolStr) {
3454 return !boolStr ? false :
3455 !strcmp(boolStr, CameraParameters::TRUE) ? true :
3456 false;
3457}
3458
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07003459int Camera2Client::degToTransform(int degrees, bool mirror) {
3460 if (!mirror) {
3461 if (degrees == 0) return 0;
3462 else if (degrees == 90) return HAL_TRANSFORM_ROT_90;
3463 else if (degrees == 180) return HAL_TRANSFORM_ROT_180;
3464 else if (degrees == 270) return HAL_TRANSFORM_ROT_270;
3465 } else { // Do mirror (horizontal flip)
3466 if (degrees == 0) { // FLIP_H and ROT_0
3467 return HAL_TRANSFORM_FLIP_H;
3468 } else if (degrees == 90) { // FLIP_H and ROT_90
3469 return HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90;
3470 } else if (degrees == 180) { // FLIP_H and ROT_180
3471 return HAL_TRANSFORM_FLIP_V;
3472 } else if (degrees == 270) { // FLIP_H and ROT_270
3473 return HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90;
3474 }
3475 }
3476 ALOGE("%s: Bad input: %d", __FUNCTION__, degrees);
3477 return -1;
3478}
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07003479
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07003480} // namespace android