blob: 4566c75d289a0686321ed292925f1cc720ab8f16 [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 }
1793 if (sendCompletedMessage) {
1794 mCameraClient->notifyCallback(CAMERA_MSG_FOCUS, success ? 1 : 0, 0);
1795 }
1796 if (sendMovingMessage) {
1797 mCameraClient->notifyCallback(CAMERA_MSG_FOCUS_MOVE,
1798 afInMotion ? 1 : 0, 0);
1799 }
1800
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -07001801}
1802
1803void Camera2Client::notifyAutoExposure(uint8_t newState, int triggerId) {
1804 ALOGV("%s: Autoexposure state now %d, last trigger %d",
1805 __FUNCTION__, newState, triggerId);
1806}
1807
1808void Camera2Client::notifyAutoWhitebalance(uint8_t newState, int triggerId) {
1809 ALOGV("%s: Auto-whitebalance state now %d, last trigger %d",
1810 __FUNCTION__, newState, triggerId);
1811}
1812
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001813void Camera2Client::onCaptureAvailable() {
1814 ATRACE_CALL();
1815 status_t res;
1816 sp<ICameraClient> currentClient;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001817 ALOGV("%s: Camera %d: Still capture available", __FUNCTION__, mCameraId);
1818
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001819 CpuConsumer::LockedBuffer imgBuffer;
1820 {
1821 Mutex::Autolock icl(mICameraLock);
1822
1823 // TODO: Signal errors here upstream
1824 if (mState != STILL_CAPTURE && mState != VIDEO_SNAPSHOT) {
1825 ALOGE("%s: Camera %d: Still image produced unexpectedly!",
1826 __FUNCTION__, mCameraId);
1827 return;
1828 }
1829
1830 res = mCaptureConsumer->lockNextBuffer(&imgBuffer);
1831 if (res != OK) {
1832 ALOGE("%s: Camera %d: Error receiving still image buffer: %s (%d)",
1833 __FUNCTION__, mCameraId, strerror(-res), res);
1834 return;
1835 }
1836
1837 if (imgBuffer.format != HAL_PIXEL_FORMAT_BLOB) {
1838 ALOGE("%s: Camera %d: Unexpected format for still image: "
1839 "%x, expected %x", __FUNCTION__, mCameraId,
1840 imgBuffer.format,
1841 HAL_PIXEL_FORMAT_BLOB);
1842 mCaptureConsumer->unlockBuffer(imgBuffer);
1843 return;
1844 }
1845
1846 // TODO: Optimize this to avoid memcopy
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001847 void* captureMemory = mCaptureHeap->mHeap->getBase();
1848 size_t size = mCaptureHeap->mHeap->getSize();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001849 memcpy(captureMemory, imgBuffer.data, size);
1850
1851 mCaptureConsumer->unlockBuffer(imgBuffer);
1852
1853 currentClient = mCameraClient;
1854 switch (mState) {
1855 case STILL_CAPTURE:
1856 mState = STOPPED;
1857 break;
1858 case VIDEO_SNAPSHOT:
1859 mState = RECORD;
1860 break;
1861 default:
1862 ALOGE("%s: Camera %d: Unexpected state %d", __FUNCTION__,
1863 mCameraId, mState);
1864 break;
1865 }
1866 }
1867 // Call outside mICameraLock to allow re-entrancy from notification
1868 if (currentClient != 0) {
1869 currentClient->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001870 mCaptureHeap->mBuffers[0], NULL);
1871 }
1872}
1873
1874void Camera2Client::onRecordingFrameAvailable() {
1875 ATRACE_CALL();
1876 status_t res;
1877 sp<ICameraClient> currentClient;
1878 size_t heapIdx = 0;
1879 nsecs_t timestamp;
1880 {
1881 Mutex::Autolock icl(mICameraLock);
1882 // TODO: Signal errors here upstream
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001883 bool discardData = false;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001884 if (mState != RECORD && mState != VIDEO_SNAPSHOT) {
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001885 ALOGV("%s: Camera %d: Discarding recording image buffers received after "
1886 "recording done",
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001887 __FUNCTION__, mCameraId);
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001888 discardData = true;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001889 }
1890
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001891 buffer_handle_t imgBuffer;
1892 res = mRecordingConsumer->getNextBuffer(&imgBuffer, &timestamp);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001893 if (res != OK) {
1894 ALOGE("%s: Camera %d: Error receiving recording buffer: %s (%d)",
1895 __FUNCTION__, mCameraId, strerror(-res), res);
1896 return;
1897 }
1898
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001899 if (discardData) {
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001900 mRecordingConsumer->freeBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001901 return;
1902 }
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001903
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001904 if (mRecordingHeap == 0) {
1905 const size_t bufferSize = 4 + sizeof(buffer_handle_t);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001906 ALOGV("%s: Camera %d: Creating recording heap with %d buffers of "
1907 "size %d bytes", __FUNCTION__, mCameraId,
James Dong983cf232012-08-01 16:39:55 -07001908 mRecordingHeapCount, bufferSize);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001909 if (mRecordingHeap != 0) {
1910 ALOGV("%s: Camera %d: Previous heap has size %d "
1911 "(new will be %d) bytes", __FUNCTION__, mCameraId,
1912 mRecordingHeap->mHeap->getSize(),
James Dong983cf232012-08-01 16:39:55 -07001913 bufferSize * mRecordingHeapCount);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001914 }
1915 // Need to allocate memory for heap
1916 mRecordingHeap.clear();
1917
James Dong983cf232012-08-01 16:39:55 -07001918 mRecordingHeap = new Camera2Heap(bufferSize, mRecordingHeapCount,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001919 "Camera2Client::RecordingHeap");
1920 if (mRecordingHeap->mHeap->getSize() == 0) {
1921 ALOGE("%s: Camera %d: Unable to allocate memory for recording",
1922 __FUNCTION__, mCameraId);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001923 mRecordingConsumer->freeBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001924 return;
1925 }
1926 mRecordingHeapHead = 0;
James Dong983cf232012-08-01 16:39:55 -07001927 mRecordingHeapFree = mRecordingHeapCount;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001928 }
1929
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001930 if ( mRecordingHeapFree == 0) {
1931 ALOGE("%s: Camera %d: No free recording buffers, dropping frame",
1932 __FUNCTION__, mCameraId);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001933 mRecordingConsumer->freeBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001934 return;
1935 }
1936 heapIdx = mRecordingHeapHead;
James Dong983cf232012-08-01 16:39:55 -07001937 mRecordingHeapHead = (mRecordingHeapHead + 1) % mRecordingHeapCount;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001938 mRecordingHeapFree--;
1939
1940 ALOGV("%s: Camera %d: Timestamp %lld",
1941 __FUNCTION__, mCameraId, timestamp);
1942
1943 ssize_t offset;
1944 size_t size;
1945 sp<IMemoryHeap> heap =
1946 mRecordingHeap->mBuffers[heapIdx]->getMemory(&offset,
1947 &size);
1948
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001949 uint8_t *data = (uint8_t*)heap->getBase() + offset;
1950 uint32_t type = kMetadataBufferTypeGrallocSource;
1951 memcpy(data, &type, 4);
1952 memcpy(data + 4, &imgBuffer, sizeof(buffer_handle_t));
1953 ALOGV("%s: Camera %d: Sending out buffer_handle_t %p",
Eino-Ville Talvala803cbf62012-07-25 15:23:36 -07001954 __FUNCTION__, mCameraId, imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001955 currentClient = mCameraClient;
1956 }
1957 // Call outside mICameraLock to allow re-entrancy from notification
1958 if (currentClient != 0) {
1959 currentClient->dataCallbackTimestamp(timestamp,
1960 CAMERA_MSG_VIDEO_FRAME,
1961 mRecordingHeap->mBuffers[heapIdx]);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001962 }
1963}
1964
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001965camera_metadata_entry_t Camera2Client::staticInfo(uint32_t tag,
1966 size_t minCount, size_t maxCount) {
1967 status_t res;
1968 camera_metadata_entry_t entry;
1969 res = find_camera_metadata_entry(mDevice->info(),
1970 tag,
1971 &entry);
1972 if (CC_UNLIKELY( res != OK )) {
1973 const char* tagSection = get_camera_metadata_section_name(tag);
1974 if (tagSection == NULL) tagSection = "<unknown>";
1975 const char* tagName = get_camera_metadata_tag_name(tag);
1976 if (tagName == NULL) tagName = "<unknown>";
1977
1978 ALOGE("Error finding static metadata entry '%s.%s' (%x): %s (%d)",
1979 tagSection, tagName, tag, strerror(-res), res);
1980 entry.count = 0;
1981 entry.data.u8 = NULL;
1982 } else if (CC_UNLIKELY(
1983 (minCount != 0 && entry.count < minCount) ||
1984 (maxCount != 0 && entry.count > maxCount) ) ) {
1985 const char* tagSection = get_camera_metadata_section_name(tag);
1986 if (tagSection == NULL) tagSection = "<unknown>";
1987 const char* tagName = get_camera_metadata_tag_name(tag);
1988 if (tagName == NULL) tagName = "<unknown>";
1989 ALOGE("Malformed static metadata entry '%s.%s' (%x):"
1990 "Expected between %d and %d values, but got %d values",
1991 tagSection, tagName, tag, minCount, maxCount, entry.count);
1992 entry.count = 0;
1993 entry.data.u8 = NULL;
1994 }
1995
1996 return entry;
1997}
1998
1999/** Utility methods */
2000
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002001
2002status_t Camera2Client::buildDefaultParameters() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07002003 ATRACE_CALL();
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002004 LockedParameters::Key k(mParameters);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07002005
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002006 status_t res;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002007 CameraParameters params;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002008
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002009 camera_metadata_entry_t availableProcessedSizes =
2010 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES, 2);
2011 if (!availableProcessedSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002012
2013 // TODO: Pick more intelligently
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002014 k.mParameters.previewWidth = availableProcessedSizes.data.i32[0];
2015 k.mParameters.previewHeight = availableProcessedSizes.data.i32[1];
2016 k.mParameters.videoWidth = k.mParameters.previewWidth;
2017 k.mParameters.videoHeight = k.mParameters.previewHeight;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002018
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002019 params.setPreviewSize(k.mParameters.previewWidth, k.mParameters.previewHeight);
2020 params.setVideoSize(k.mParameters.videoWidth, k.mParameters.videoHeight);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002021 params.set(CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO,
2022 String8::format("%dx%d",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002023 k.mParameters.previewWidth, k.mParameters.previewHeight));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002024 {
2025 String8 supportedPreviewSizes;
2026 for (size_t i=0; i < availableProcessedSizes.count; i += 2) {
2027 if (i != 0) supportedPreviewSizes += ",";
2028 supportedPreviewSizes += String8::format("%dx%d",
2029 availableProcessedSizes.data.i32[i],
2030 availableProcessedSizes.data.i32[i+1]);
2031 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002032 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002033 supportedPreviewSizes);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002034 params.set(CameraParameters::KEY_SUPPORTED_VIDEO_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002035 supportedPreviewSizes);
2036 }
2037
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002038 camera_metadata_entry_t availableFpsRanges =
2039 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
2040 if (!availableFpsRanges.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002041
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002042 k.mParameters.previewFpsRange[0] = availableFpsRanges.data.i32[0];
2043 k.mParameters.previewFpsRange[1] = availableFpsRanges.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002044
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002045 params.set(CameraParameters::KEY_PREVIEW_FPS_RANGE,
2046 String8::format("%d,%d",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002047 k.mParameters.previewFpsRange[0],
2048 k.mParameters.previewFpsRange[1]));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002049
2050 {
2051 String8 supportedPreviewFpsRange;
2052 for (size_t i=0; i < availableFpsRanges.count; i += 2) {
2053 if (i != 0) supportedPreviewFpsRange += ",";
2054 supportedPreviewFpsRange += String8::format("(%d,%d)",
2055 availableFpsRanges.data.i32[i],
2056 availableFpsRanges.data.i32[i+1]);
2057 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002058 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002059 supportedPreviewFpsRange);
2060 }
2061
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002062 k.mParameters.previewFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002063 params.set(CameraParameters::KEY_PREVIEW_FORMAT,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002064 formatEnumToString(k.mParameters.previewFormat)); // NV21
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002065
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002066 k.mParameters.previewTransform = degToTransform(0,
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07002067 mCameraFacing == CAMERA_FACING_FRONT);
2068
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002069 camera_metadata_entry_t availableFormats =
2070 staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
2071
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002072 {
2073 String8 supportedPreviewFormats;
2074 bool addComma = false;
2075 for (size_t i=0; i < availableFormats.count; i++) {
2076 if (addComma) supportedPreviewFormats += ",";
2077 addComma = true;
2078 switch (availableFormats.data.i32[i]) {
2079 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002080 supportedPreviewFormats +=
2081 CameraParameters::PIXEL_FORMAT_YUV422SP;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002082 break;
2083 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002084 supportedPreviewFormats +=
2085 CameraParameters::PIXEL_FORMAT_YUV420SP;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002086 break;
2087 case HAL_PIXEL_FORMAT_YCbCr_422_I:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002088 supportedPreviewFormats +=
2089 CameraParameters::PIXEL_FORMAT_YUV422I;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002090 break;
2091 case HAL_PIXEL_FORMAT_YV12:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002092 supportedPreviewFormats +=
2093 CameraParameters::PIXEL_FORMAT_YUV420P;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002094 break;
2095 case HAL_PIXEL_FORMAT_RGB_565:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002096 supportedPreviewFormats +=
2097 CameraParameters::PIXEL_FORMAT_RGB565;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002098 break;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07002099 case HAL_PIXEL_FORMAT_RGBA_8888:
2100 supportedPreviewFormats +=
2101 CameraParameters::PIXEL_FORMAT_RGBA8888;
2102 break;
2103 // Not advertizing JPEG, RAW_SENSOR, etc, for preview formats
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002104 case HAL_PIXEL_FORMAT_RAW_SENSOR:
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07002105 case HAL_PIXEL_FORMAT_BLOB:
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002106 addComma = false;
2107 break;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07002108
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002109 default:
2110 ALOGW("%s: Camera %d: Unknown preview format: %x",
2111 __FUNCTION__, mCameraId, availableFormats.data.i32[i]);
2112 addComma = false;
2113 break;
2114 }
2115 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002116 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002117 supportedPreviewFormats);
2118 }
2119
2120 // PREVIEW_FRAME_RATE / SUPPORTED_PREVIEW_FRAME_RATES are deprecated, but
2121 // still have to do something sane for them
2122
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002123 params.set(CameraParameters::KEY_PREVIEW_FRAME_RATE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002124 k.mParameters.previewFpsRange[0]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002125
2126 {
2127 String8 supportedPreviewFrameRates;
2128 for (size_t i=0; i < availableFpsRanges.count; i += 2) {
2129 if (i != 0) supportedPreviewFrameRates += ",";
2130 supportedPreviewFrameRates += String8::format("%d",
2131 availableFpsRanges.data.i32[i]);
2132 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002133 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002134 supportedPreviewFrameRates);
2135 }
2136
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002137 camera_metadata_entry_t availableJpegSizes =
2138 staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES, 2);
2139 if (!availableJpegSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002140
2141 // TODO: Pick maximum
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002142 k.mParameters.pictureWidth = availableJpegSizes.data.i32[0];
2143 k.mParameters.pictureHeight = availableJpegSizes.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002144
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002145 params.setPictureSize(k.mParameters.pictureWidth,
2146 k.mParameters.pictureHeight);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002147
2148 {
2149 String8 supportedPictureSizes;
2150 for (size_t i=0; i < availableJpegSizes.count; i += 2) {
2151 if (i != 0) supportedPictureSizes += ",";
2152 supportedPictureSizes += String8::format("%dx%d",
2153 availableJpegSizes.data.i32[i],
2154 availableJpegSizes.data.i32[i+1]);
2155 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002156 params.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002157 supportedPictureSizes);
2158 }
2159
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002160 params.setPictureFormat(CameraParameters::PIXEL_FORMAT_JPEG);
2161 params.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS,
2162 CameraParameters::PIXEL_FORMAT_JPEG);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002163
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002164 camera_metadata_entry_t availableJpegThumbnailSizes =
2165 staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES, 2);
2166 if (!availableJpegThumbnailSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002167
2168 // TODO: Pick default thumbnail size sensibly
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002169 k.mParameters.jpegThumbSize[0] = availableJpegThumbnailSizes.data.i32[0];
2170 k.mParameters.jpegThumbSize[1] = availableJpegThumbnailSizes.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002171
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002172 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002173 k.mParameters.jpegThumbSize[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002174 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002175 k.mParameters.jpegThumbSize[1]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002176
2177 {
2178 String8 supportedJpegThumbSizes;
2179 for (size_t i=0; i < availableJpegThumbnailSizes.count; i += 2) {
2180 if (i != 0) supportedJpegThumbSizes += ",";
2181 supportedJpegThumbSizes += String8::format("%dx%d",
2182 availableJpegThumbnailSizes.data.i32[i],
2183 availableJpegThumbnailSizes.data.i32[i+1]);
2184 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002185 params.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002186 supportedJpegThumbSizes);
2187 }
2188
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002189 k.mParameters.jpegThumbQuality = 90;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002190 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002191 k.mParameters.jpegThumbQuality);
2192 k.mParameters.jpegQuality = 90;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002193 params.set(CameraParameters::KEY_JPEG_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002194 k.mParameters.jpegQuality);
2195 k.mParameters.jpegRotation = 0;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002196 params.set(CameraParameters::KEY_ROTATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002197 k.mParameters.jpegRotation);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002198
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002199 k.mParameters.gpsEnabled = false;
2200 k.mParameters.gpsProcessingMethod = "unknown";
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002201 // GPS fields in CameraParameters are not set by implementation
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002202
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002203 k.mParameters.wbMode = ANDROID_CONTROL_AWB_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002204 params.set(CameraParameters::KEY_WHITE_BALANCE,
2205 CameraParameters::WHITE_BALANCE_AUTO);
2206
2207 camera_metadata_entry_t availableWhiteBalanceModes =
2208 staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002209 {
2210 String8 supportedWhiteBalance;
2211 bool addComma = false;
2212 for (size_t i=0; i < availableWhiteBalanceModes.count; i++) {
2213 if (addComma) supportedWhiteBalance += ",";
2214 addComma = true;
2215 switch (availableWhiteBalanceModes.data.u8[i]) {
2216 case ANDROID_CONTROL_AWB_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002217 supportedWhiteBalance +=
2218 CameraParameters::WHITE_BALANCE_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002219 break;
2220 case ANDROID_CONTROL_AWB_INCANDESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002221 supportedWhiteBalance +=
2222 CameraParameters::WHITE_BALANCE_INCANDESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002223 break;
2224 case ANDROID_CONTROL_AWB_FLUORESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002225 supportedWhiteBalance +=
2226 CameraParameters::WHITE_BALANCE_FLUORESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002227 break;
2228 case ANDROID_CONTROL_AWB_WARM_FLUORESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002229 supportedWhiteBalance +=
2230 CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002231 break;
2232 case ANDROID_CONTROL_AWB_DAYLIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002233 supportedWhiteBalance +=
2234 CameraParameters::WHITE_BALANCE_DAYLIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002235 break;
2236 case ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002237 supportedWhiteBalance +=
2238 CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002239 break;
2240 case ANDROID_CONTROL_AWB_TWILIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002241 supportedWhiteBalance +=
2242 CameraParameters::WHITE_BALANCE_TWILIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002243 break;
2244 case ANDROID_CONTROL_AWB_SHADE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002245 supportedWhiteBalance +=
2246 CameraParameters::WHITE_BALANCE_SHADE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002247 break;
2248 // Skipping values not mappable to v1 API
2249 case ANDROID_CONTROL_AWB_OFF:
2250 addComma = false;
2251 break;
2252 default:
2253 ALOGW("%s: Camera %d: Unknown white balance value: %d",
2254 __FUNCTION__, mCameraId,
2255 availableWhiteBalanceModes.data.u8[i]);
2256 addComma = false;
2257 break;
2258 }
2259 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002260 params.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002261 supportedWhiteBalance);
2262 }
2263
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002264 k.mParameters.effectMode = ANDROID_CONTROL_EFFECT_OFF;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002265 params.set(CameraParameters::KEY_EFFECT,
2266 CameraParameters::EFFECT_NONE);
2267
2268 camera_metadata_entry_t availableEffects =
2269 staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
2270 if (!availableEffects.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002271 {
2272 String8 supportedEffects;
2273 bool addComma = false;
2274 for (size_t i=0; i < availableEffects.count; i++) {
2275 if (addComma) supportedEffects += ",";
2276 addComma = true;
2277 switch (availableEffects.data.u8[i]) {
2278 case ANDROID_CONTROL_EFFECT_OFF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002279 supportedEffects +=
2280 CameraParameters::EFFECT_NONE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002281 break;
2282 case ANDROID_CONTROL_EFFECT_MONO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002283 supportedEffects +=
2284 CameraParameters::EFFECT_MONO;
2285 break;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002286 case ANDROID_CONTROL_EFFECT_NEGATIVE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002287 supportedEffects +=
2288 CameraParameters::EFFECT_NEGATIVE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002289 break;
2290 case ANDROID_CONTROL_EFFECT_SOLARIZE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002291 supportedEffects +=
2292 CameraParameters::EFFECT_SOLARIZE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002293 break;
2294 case ANDROID_CONTROL_EFFECT_SEPIA:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002295 supportedEffects +=
2296 CameraParameters::EFFECT_SEPIA;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002297 break;
2298 case ANDROID_CONTROL_EFFECT_POSTERIZE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002299 supportedEffects +=
2300 CameraParameters::EFFECT_POSTERIZE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002301 break;
2302 case ANDROID_CONTROL_EFFECT_WHITEBOARD:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002303 supportedEffects +=
2304 CameraParameters::EFFECT_WHITEBOARD;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002305 break;
2306 case ANDROID_CONTROL_EFFECT_BLACKBOARD:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002307 supportedEffects +=
2308 CameraParameters::EFFECT_BLACKBOARD;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002309 break;
2310 case ANDROID_CONTROL_EFFECT_AQUA:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002311 supportedEffects +=
2312 CameraParameters::EFFECT_AQUA;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002313 break;
2314 default:
2315 ALOGW("%s: Camera %d: Unknown effect value: %d",
2316 __FUNCTION__, mCameraId, availableEffects.data.u8[i]);
2317 addComma = false;
2318 break;
2319 }
2320 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002321 params.set(CameraParameters::KEY_SUPPORTED_EFFECTS, supportedEffects);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002322 }
2323
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002324 k.mParameters.antibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002325 params.set(CameraParameters::KEY_ANTIBANDING,
2326 CameraParameters::ANTIBANDING_AUTO);
2327
2328 camera_metadata_entry_t availableAntibandingModes =
2329 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
2330 if (!availableAntibandingModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002331 {
2332 String8 supportedAntibanding;
2333 bool addComma = false;
2334 for (size_t i=0; i < availableAntibandingModes.count; i++) {
2335 if (addComma) supportedAntibanding += ",";
2336 addComma = true;
2337 switch (availableAntibandingModes.data.u8[i]) {
2338 case ANDROID_CONTROL_AE_ANTIBANDING_OFF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002339 supportedAntibanding +=
2340 CameraParameters::ANTIBANDING_OFF;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002341 break;
2342 case ANDROID_CONTROL_AE_ANTIBANDING_50HZ:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002343 supportedAntibanding +=
2344 CameraParameters::ANTIBANDING_50HZ;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002345 break;
2346 case ANDROID_CONTROL_AE_ANTIBANDING_60HZ:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002347 supportedAntibanding +=
2348 CameraParameters::ANTIBANDING_60HZ;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002349 break;
2350 case ANDROID_CONTROL_AE_ANTIBANDING_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002351 supportedAntibanding +=
2352 CameraParameters::ANTIBANDING_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002353 break;
2354 default:
2355 ALOGW("%s: Camera %d: Unknown antibanding value: %d",
2356 __FUNCTION__, mCameraId,
2357 availableAntibandingModes.data.u8[i]);
2358 addComma = false;
2359 break;
2360 }
2361 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002362 params.set(CameraParameters::KEY_SUPPORTED_ANTIBANDING,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002363 supportedAntibanding);
2364 }
2365
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002366 k.mParameters.sceneMode = ANDROID_CONTROL_OFF;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002367 params.set(CameraParameters::KEY_SCENE_MODE,
2368 CameraParameters::SCENE_MODE_AUTO);
2369
2370 camera_metadata_entry_t availableSceneModes =
2371 staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
2372 if (!availableSceneModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002373 {
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002374 String8 supportedSceneModes(CameraParameters::SCENE_MODE_AUTO);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002375 bool addComma = true;
2376 bool noSceneModes = false;
2377 for (size_t i=0; i < availableSceneModes.count; i++) {
2378 if (addComma) supportedSceneModes += ",";
2379 addComma = true;
2380 switch (availableSceneModes.data.u8[i]) {
2381 case ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED:
2382 noSceneModes = true;
2383 break;
2384 case ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY:
2385 // Not in old API
2386 addComma = false;
2387 break;
2388 case ANDROID_CONTROL_SCENE_MODE_ACTION:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002389 supportedSceneModes +=
2390 CameraParameters::SCENE_MODE_ACTION;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002391 break;
2392 case ANDROID_CONTROL_SCENE_MODE_PORTRAIT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002393 supportedSceneModes +=
2394 CameraParameters::SCENE_MODE_PORTRAIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002395 break;
2396 case ANDROID_CONTROL_SCENE_MODE_LANDSCAPE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002397 supportedSceneModes +=
2398 CameraParameters::SCENE_MODE_LANDSCAPE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002399 break;
2400 case ANDROID_CONTROL_SCENE_MODE_NIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002401 supportedSceneModes +=
2402 CameraParameters::SCENE_MODE_NIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002403 break;
2404 case ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002405 supportedSceneModes +=
2406 CameraParameters::SCENE_MODE_NIGHT_PORTRAIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002407 break;
2408 case ANDROID_CONTROL_SCENE_MODE_THEATRE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002409 supportedSceneModes +=
2410 CameraParameters::SCENE_MODE_THEATRE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002411 break;
2412 case ANDROID_CONTROL_SCENE_MODE_BEACH:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002413 supportedSceneModes +=
2414 CameraParameters::SCENE_MODE_BEACH;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002415 break;
2416 case ANDROID_CONTROL_SCENE_MODE_SNOW:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002417 supportedSceneModes +=
2418 CameraParameters::SCENE_MODE_SNOW;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002419 break;
2420 case ANDROID_CONTROL_SCENE_MODE_SUNSET:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002421 supportedSceneModes +=
2422 CameraParameters::SCENE_MODE_SUNSET;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002423 break;
2424 case ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002425 supportedSceneModes +=
2426 CameraParameters::SCENE_MODE_STEADYPHOTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002427 break;
2428 case ANDROID_CONTROL_SCENE_MODE_FIREWORKS:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002429 supportedSceneModes +=
2430 CameraParameters::SCENE_MODE_FIREWORKS;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002431 break;
2432 case ANDROID_CONTROL_SCENE_MODE_SPORTS:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002433 supportedSceneModes +=
2434 CameraParameters::SCENE_MODE_SPORTS;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002435 break;
2436 case ANDROID_CONTROL_SCENE_MODE_PARTY:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002437 supportedSceneModes +=
2438 CameraParameters::SCENE_MODE_PARTY;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002439 break;
2440 case ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002441 supportedSceneModes +=
2442 CameraParameters::SCENE_MODE_CANDLELIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002443 break;
2444 case ANDROID_CONTROL_SCENE_MODE_BARCODE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002445 supportedSceneModes +=
2446 CameraParameters::SCENE_MODE_BARCODE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002447 break;
2448 default:
2449 ALOGW("%s: Camera %d: Unknown scene mode value: %d",
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002450 __FUNCTION__, mCameraId,
2451 availableSceneModes.data.u8[i]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002452 addComma = false;
2453 break;
2454 }
2455 }
2456 if (!noSceneModes) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002457 params.set(CameraParameters::KEY_SUPPORTED_SCENE_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002458 supportedSceneModes);
2459 }
2460 }
2461
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002462 camera_metadata_entry_t flashAvailable =
2463 staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
2464 if (!flashAvailable.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002465
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002466 camera_metadata_entry_t availableAeModes =
2467 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
2468 if (!availableAeModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002469
2470 if (flashAvailable.data.u8[0]) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002471 k.mParameters.flashMode = Parameters::FLASH_MODE_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002472 params.set(CameraParameters::KEY_FLASH_MODE,
2473 CameraParameters::FLASH_MODE_AUTO);
2474
2475 String8 supportedFlashModes(CameraParameters::FLASH_MODE_OFF);
2476 supportedFlashModes = supportedFlashModes +
2477 "," + CameraParameters::FLASH_MODE_AUTO +
2478 "," + CameraParameters::FLASH_MODE_ON +
2479 "," + CameraParameters::FLASH_MODE_TORCH;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002480 for (size_t i=0; i < availableAeModes.count; i++) {
2481 if (availableAeModes.data.u8[i] ==
2482 ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002483 supportedFlashModes = supportedFlashModes + "," +
2484 CameraParameters::FLASH_MODE_RED_EYE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002485 break;
2486 }
2487 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002488 params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002489 supportedFlashModes);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002490 } else {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002491 k.mParameters.flashMode = Parameters::FLASH_MODE_OFF;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002492 params.set(CameraParameters::KEY_FLASH_MODE,
2493 CameraParameters::FLASH_MODE_OFF);
2494 params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
2495 CameraParameters::FLASH_MODE_OFF);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002496 }
2497
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002498 camera_metadata_entry_t minFocusDistance =
2499 staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE, 1, 1);
2500 if (!minFocusDistance.count) return NO_INIT;
2501
2502 camera_metadata_entry_t availableAfModes =
2503 staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
2504 if (!availableAfModes.count) return NO_INIT;
2505
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002506 if (minFocusDistance.data.f[0] == 0) {
2507 // Fixed-focus lens
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002508 k.mParameters.focusMode = Parameters::FOCUS_MODE_FIXED;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002509 params.set(CameraParameters::KEY_FOCUS_MODE,
2510 CameraParameters::FOCUS_MODE_FIXED);
2511 params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
2512 CameraParameters::FOCUS_MODE_FIXED);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002513 } else {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002514 k.mParameters.focusMode = Parameters::FOCUS_MODE_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002515 params.set(CameraParameters::KEY_FOCUS_MODE,
2516 CameraParameters::FOCUS_MODE_AUTO);
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07002517 String8 supportedFocusModes(CameraParameters::FOCUS_MODE_INFINITY);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002518 bool addComma = true;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002519
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002520 for (size_t i=0; i < availableAfModes.count; i++) {
2521 if (addComma) supportedFocusModes += ",";
2522 addComma = true;
2523 switch (availableAfModes.data.u8[i]) {
2524 case ANDROID_CONTROL_AF_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002525 supportedFocusModes +=
2526 CameraParameters::FOCUS_MODE_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002527 break;
2528 case ANDROID_CONTROL_AF_MACRO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002529 supportedFocusModes +=
2530 CameraParameters::FOCUS_MODE_MACRO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002531 break;
2532 case ANDROID_CONTROL_AF_CONTINUOUS_VIDEO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002533 supportedFocusModes +=
2534 CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002535 break;
2536 case ANDROID_CONTROL_AF_CONTINUOUS_PICTURE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002537 supportedFocusModes +=
2538 CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002539 break;
2540 case ANDROID_CONTROL_AF_EDOF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002541 supportedFocusModes +=
2542 CameraParameters::FOCUS_MODE_EDOF;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002543 break;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002544 // Not supported in old API
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002545 case ANDROID_CONTROL_AF_OFF:
2546 addComma = false;
2547 break;
2548 default:
2549 ALOGW("%s: Camera %d: Unknown AF mode value: %d",
2550 __FUNCTION__, mCameraId, availableAfModes.data.u8[i]);
2551 addComma = false;
2552 break;
2553 }
2554 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002555 params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002556 supportedFocusModes);
2557 }
2558
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002559 camera_metadata_entry_t max3aRegions =
2560 staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1);
2561 if (!max3aRegions.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002562
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002563 params.set(CameraParameters::KEY_MAX_NUM_FOCUS_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002564 max3aRegions.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002565 params.set(CameraParameters::KEY_FOCUS_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002566 "(0,0,0,0,0)");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002567 k.mParameters.focusingAreas.clear();
2568 k.mParameters.focusingAreas.add(Parameters::Area(0,0,0,0,0));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002569
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002570 camera_metadata_entry_t availableFocalLengths =
2571 staticInfo(ANDROID_LENS_AVAILABLE_FOCAL_LENGTHS);
2572 if (!availableFocalLengths.count) return NO_INIT;
2573
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002574 float minFocalLength = availableFocalLengths.data.f[0];
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002575 params.setFloat(CameraParameters::KEY_FOCAL_LENGTH, minFocalLength);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002576
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002577 camera_metadata_entry_t sensorSize =
2578 staticInfo(ANDROID_SENSOR_PHYSICAL_SIZE, 2, 2);
2579 if (!sensorSize.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002580
2581 // The fields of view here assume infinity focus, maximum wide angle
2582 float horizFov = 180 / M_PI *
2583 2 * atanf(sensorSize.data.f[0] / (2 * minFocalLength));
2584 float vertFov = 180 / M_PI *
2585 2 * atanf(sensorSize.data.f[1] / (2 * minFocalLength));
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002586 params.setFloat(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, horizFov);
2587 params.setFloat(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, vertFov);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002588
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002589 k.mParameters.exposureCompensation = 0;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002590 params.set(CameraParameters::KEY_EXPOSURE_COMPENSATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002591 k.mParameters.exposureCompensation);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002592
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002593 camera_metadata_entry_t exposureCompensationRange =
2594 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE, 2, 2);
2595 if (!exposureCompensationRange.count) return NO_INIT;
2596
2597 params.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002598 exposureCompensationRange.data.i32[1]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002599 params.set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002600 exposureCompensationRange.data.i32[0]);
2601
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002602 camera_metadata_entry_t exposureCompensationStep =
2603 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_STEP, 1, 1);
2604 if (!exposureCompensationStep.count) return NO_INIT;
2605
2606 params.setFloat(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP,
Eino-Ville Talvalad6f8e082012-08-02 16:00:35 -07002607 (float)exposureCompensationStep.data.r[0].numerator /
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002608 exposureCompensationStep.data.r[0].denominator);
2609
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002610 k.mParameters.autoExposureLock = false;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002611 params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK,
2612 CameraParameters::FALSE);
2613 params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED,
2614 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002615
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002616 k.mParameters.autoWhiteBalanceLock = false;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002617 params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK,
2618 CameraParameters::FALSE);
2619 params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED,
2620 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002621
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002622 k.mParameters.meteringAreas.add(Parameters::Area(0, 0, 0, 0, 0));
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002623 params.set(CameraParameters::KEY_MAX_NUM_METERING_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002624 max3aRegions.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002625 params.set(CameraParameters::KEY_METERING_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002626 "(0,0,0,0,0)");
2627
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002628 k.mParameters.zoom = 0;
2629 params.set(CameraParameters::KEY_ZOOM, k.mParameters.zoom);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002630 params.set(CameraParameters::KEY_MAX_ZOOM, NUM_ZOOM_STEPS - 1);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002631
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002632 camera_metadata_entry_t maxDigitalZoom =
2633 staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM, 1, 1);
2634 if (!maxDigitalZoom.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002635
2636 {
2637 String8 zoomRatios;
2638 float zoom = 1.f;
2639 float zoomIncrement = (maxDigitalZoom.data.f[0] - zoom) /
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002640 (NUM_ZOOM_STEPS-1);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002641 bool addComma = false;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002642 for (size_t i=0; i < NUM_ZOOM_STEPS; i++) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002643 if (addComma) zoomRatios += ",";
2644 addComma = true;
2645 zoomRatios += String8::format("%d", static_cast<int>(zoom * 100));
2646 zoom += zoomIncrement;
2647 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002648 params.set(CameraParameters::KEY_ZOOM_RATIOS, zoomRatios);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002649 }
2650
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002651 params.set(CameraParameters::KEY_ZOOM_SUPPORTED,
2652 CameraParameters::TRUE);
2653 params.set(CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED,
2654 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002655
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002656 params.set(CameraParameters::KEY_FOCUS_DISTANCES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002657 "Infinity,Infinity,Infinity");
2658
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002659 camera_metadata_entry_t maxFacesDetected =
2660 staticInfo(ANDROID_STATS_MAX_FACE_COUNT, 1, 1);
2661 params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002662 maxFacesDetected.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002663 params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002664 0);
2665
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002666 params.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT,
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002667 CameraParameters::PIXEL_FORMAT_ANDROID_OPAQUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002668
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002669 params.set(CameraParameters::KEY_RECORDING_HINT,
2670 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002671
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002672 params.set(CameraParameters::KEY_VIDEO_SNAPSHOT_SUPPORTED,
2673 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002674
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002675 params.set(CameraParameters::KEY_VIDEO_STABILIZATION,
2676 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002677
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002678 camera_metadata_entry_t availableVideoStabilizationModes =
2679 staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
2680 if (!availableVideoStabilizationModes.count) return NO_INIT;
2681
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002682 if (availableVideoStabilizationModes.count > 1) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002683 params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
2684 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002685 } else {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002686 params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
2687 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002688 }
2689
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07002690 // Set up initial state for non-Camera.Parameters state variables
2691
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002692 k.mParameters.storeMetadataInBuffers = true;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07002693 k.mParameters.playShutterSound = true;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07002694 k.mParameters.afTriggerCounter = 0;
2695 k.mParameters.currentAfTriggerId = -1;
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002696
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002697 k.mParameters.paramsFlattened = params.flatten();
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002698
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002699 return OK;
2700}
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07002701
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002702status_t Camera2Client::updatePreviewStream(const Parameters &params) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002703 ATRACE_CALL();
2704 status_t res;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002705
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002706 if (mPreviewStreamId != NO_STREAM) {
2707 // Check if stream parameters have to change
2708 uint32_t currentWidth, currentHeight;
2709 res = mDevice->getStreamInfo(mPreviewStreamId,
2710 &currentWidth, &currentHeight, 0);
2711 if (res != OK) {
2712 ALOGE("%s: Camera %d: Error querying preview stream info: "
2713 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2714 return res;
2715 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002716 if (currentWidth != (uint32_t)params.previewWidth ||
2717 currentHeight != (uint32_t)params.previewHeight) {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -07002718 ALOGV("%s: Camera %d: Preview size switch: %d x %d -> %d x %d",
2719 __FUNCTION__, mCameraId, currentWidth, currentHeight,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002720 params.previewWidth, params.previewHeight);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002721 res = mDevice->waitUntilDrained();
2722 if (res != OK) {
2723 ALOGE("%s: Camera %d: Error waiting for preview to drain: "
2724 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2725 return res;
2726 }
2727 res = mDevice->deleteStream(mPreviewStreamId);
2728 if (res != OK) {
2729 ALOGE("%s: Camera %d: Unable to delete old output stream "
2730 "for preview: %s (%d)", __FUNCTION__, mCameraId,
2731 strerror(-res), res);
2732 return res;
2733 }
2734 mPreviewStreamId = NO_STREAM;
2735 }
2736 }
2737
2738 if (mPreviewStreamId == NO_STREAM) {
2739 res = mDevice->createStream(mPreviewWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002740 params.previewWidth, params.previewHeight,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002741 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0,
2742 &mPreviewStreamId);
2743 if (res != OK) {
2744 ALOGE("%s: Camera %d: Unable to create preview stream: %s (%d)",
2745 __FUNCTION__, mCameraId, strerror(-res), res);
2746 return res;
2747 }
2748 }
2749
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07002750 res = mDevice->setStreamTransform(mPreviewStreamId,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002751 params.previewTransform);
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07002752 if (res != OK) {
2753 ALOGE("%s: Camera %d: Unable to set preview stream transform: "
2754 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2755 return res;
2756 }
2757
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002758 return OK;
2759}
2760
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002761status_t Camera2Client::updatePreviewRequest(const Parameters &params) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07002762 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002763 status_t res;
2764 if (mPreviewRequest == NULL) {
2765 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
2766 &mPreviewRequest);
2767 if (res != OK) {
2768 ALOGE("%s: Camera %d: Unable to create default preview request: "
2769 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2770 return res;
2771 }
2772 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002773
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002774 res = updateRequestCommon(mPreviewRequest, params);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002775 if (res != OK) {
2776 ALOGE("%s: Camera %d: Unable to update common entries of preview "
2777 "request: %s (%d)", __FUNCTION__, mCameraId,
2778 strerror(-res), res);
2779 return res;
2780 }
2781
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002782 return OK;
2783}
2784
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002785status_t Camera2Client::updateCaptureStream(const Parameters &params) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002786 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002787 status_t res;
2788 // Find out buffer size for JPEG
2789 camera_metadata_entry_t maxJpegSize =
2790 staticInfo(ANDROID_JPEG_MAX_SIZE);
2791 if (maxJpegSize.count == 0) {
2792 ALOGE("%s: Camera %d: Can't find ANDROID_JPEG_MAX_SIZE!",
2793 __FUNCTION__, mCameraId);
2794 return INVALID_OPERATION;
2795 }
2796
2797 if (mCaptureConsumer == 0) {
2798 // Create CPU buffer queue endpoint
2799 mCaptureConsumer = new CpuConsumer(1);
2800 mCaptureConsumer->setFrameAvailableListener(new CaptureWaiter(this));
2801 mCaptureConsumer->setName(String8("Camera2Client::CaptureConsumer"));
2802 mCaptureWindow = new SurfaceTextureClient(
2803 mCaptureConsumer->getProducerInterface());
2804 // Create memory for API consumption
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002805 mCaptureHeap = new Camera2Heap(maxJpegSize.data.i32[0], 1,
2806 "Camera2Client::CaptureHeap");
2807 if (mCaptureHeap->mHeap->getSize() == 0) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002808 ALOGE("%s: Camera %d: Unable to allocate memory for capture",
2809 __FUNCTION__, mCameraId);
2810 return NO_MEMORY;
2811 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002812 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002813
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002814 if (mCaptureStreamId != NO_STREAM) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002815 // Check if stream parameters have to change
2816 uint32_t currentWidth, currentHeight;
2817 res = mDevice->getStreamInfo(mCaptureStreamId,
2818 &currentWidth, &currentHeight, 0);
2819 if (res != OK) {
2820 ALOGE("%s: Camera %d: Error querying capture output stream info: "
2821 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2822 return res;
2823 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002824 if (currentWidth != (uint32_t)params.pictureWidth ||
2825 currentHeight != (uint32_t)params.pictureHeight) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002826 res = mDevice->deleteStream(mCaptureStreamId);
2827 if (res != OK) {
2828 ALOGE("%s: Camera %d: Unable to delete old output stream "
2829 "for capture: %s (%d)", __FUNCTION__, mCameraId,
2830 strerror(-res), res);
2831 return res;
2832 }
2833 mCaptureStreamId = NO_STREAM;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002834 }
2835 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002836
2837 if (mCaptureStreamId == NO_STREAM) {
2838 // Create stream for HAL production
2839 res = mDevice->createStream(mCaptureWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002840 params.pictureWidth, params.pictureHeight,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002841 HAL_PIXEL_FORMAT_BLOB, maxJpegSize.data.i32[0],
2842 &mCaptureStreamId);
2843 if (res != OK) {
2844 ALOGE("%s: Camera %d: Can't create output stream for capture: "
2845 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2846 return res;
2847 }
2848
2849 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002850 return OK;
2851}
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002852
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002853status_t Camera2Client::updateCaptureRequest(const Parameters &params) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002854 ATRACE_CALL();
2855 status_t res;
2856 if (mCaptureRequest == NULL) {
2857 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_STILL_CAPTURE,
2858 &mCaptureRequest);
2859 if (res != OK) {
2860 ALOGE("%s: Camera %d: Unable to create default still image request:"
2861 " %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2862 return res;
2863 }
2864 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002865
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002866 res = updateRequestCommon(mCaptureRequest, params);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002867 if (res != OK) {
2868 ALOGE("%s: Camera %d: Unable to update common entries of capture "
2869 "request: %s (%d)", __FUNCTION__, mCameraId,
2870 strerror(-res), res);
2871 return res;
2872 }
2873
2874 res = updateEntry(mCaptureRequest,
2875 ANDROID_JPEG_THUMBNAIL_SIZE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002876 params.jpegThumbSize, 2);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002877 if (res != OK) return res;
2878 res = updateEntry(mCaptureRequest,
2879 ANDROID_JPEG_THUMBNAIL_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002880 &params.jpegThumbQuality, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002881 if (res != OK) return res;
2882 res = updateEntry(mCaptureRequest,
2883 ANDROID_JPEG_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002884 &params.jpegQuality, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002885 if (res != OK) return res;
2886 res = updateEntry(mCaptureRequest,
2887 ANDROID_JPEG_ORIENTATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002888 &params.jpegRotation, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002889 if (res != OK) return res;
2890
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002891 if (params.gpsEnabled) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002892 res = updateEntry(mCaptureRequest,
2893 ANDROID_JPEG_GPS_COORDINATES,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002894 params.gpsCoordinates, 3);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002895 if (res != OK) return res;
2896 res = updateEntry(mCaptureRequest,
2897 ANDROID_JPEG_GPS_TIMESTAMP,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002898 &params.gpsTimestamp, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002899 if (res != OK) return res;
2900 res = updateEntry(mCaptureRequest,
2901 ANDROID_JPEG_GPS_PROCESSING_METHOD,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002902 params.gpsProcessingMethod.string(),
2903 params.gpsProcessingMethod.size());
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002904 if (res != OK) return res;
2905 } else {
2906 res = deleteEntry(mCaptureRequest,
2907 ANDROID_JPEG_GPS_COORDINATES);
2908 if (res != OK) return res;
2909 res = deleteEntry(mCaptureRequest,
2910 ANDROID_JPEG_GPS_TIMESTAMP);
2911 if (res != OK) return res;
2912 res = deleteEntry(mCaptureRequest,
2913 ANDROID_JPEG_GPS_PROCESSING_METHOD);
2914 if (res != OK) return res;
2915 }
2916
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002917 return OK;
2918}
2919
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002920status_t Camera2Client::updateRecordingRequest(const Parameters &params) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002921 ATRACE_CALL();
2922 status_t res;
2923 if (mRecordingRequest == NULL) {
2924 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_VIDEO_RECORD,
2925 &mRecordingRequest);
2926 if (res != OK) {
2927 ALOGE("%s: Camera %d: Unable to create default recording request:"
2928 " %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2929 return res;
2930 }
2931 }
2932
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002933 res = updateRequestCommon(mRecordingRequest, params);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002934 if (res != OK) {
2935 ALOGE("%s: Camera %d: Unable to update common entries of recording "
2936 "request: %s (%d)", __FUNCTION__, mCameraId,
2937 strerror(-res), res);
2938 return res;
2939 }
2940
2941 return OK;
2942}
2943
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002944status_t Camera2Client::updateRecordingStream(const Parameters &params) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002945 status_t res;
2946
2947 if (mRecordingConsumer == 0) {
2948 // Create CPU buffer queue endpoint
James Dong983cf232012-08-01 16:39:55 -07002949 mRecordingConsumer = new MediaConsumer(mRecordingHeapCount);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002950 mRecordingConsumer->setFrameAvailableListener(new RecordingWaiter(this));
2951 mRecordingConsumer->setName(String8("Camera2Client::RecordingConsumer"));
2952 mRecordingWindow = new SurfaceTextureClient(
2953 mRecordingConsumer->getProducerInterface());
2954 // Allocate memory later, since we don't know buffer size until receipt
2955 }
2956
2957 if (mRecordingStreamId != NO_STREAM) {
2958 // Check if stream parameters have to change
2959 uint32_t currentWidth, currentHeight;
2960 res = mDevice->getStreamInfo(mRecordingStreamId,
2961 &currentWidth, &currentHeight, 0);
2962 if (res != OK) {
2963 ALOGE("%s: Camera %d: Error querying recording output stream info: "
2964 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2965 return res;
2966 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002967 if (currentWidth != (uint32_t)params.videoWidth ||
2968 currentHeight != (uint32_t)params.videoHeight) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002969 // TODO: Should wait to be sure previous recording has finished
2970 res = mDevice->deleteStream(mRecordingStreamId);
2971 if (res != OK) {
2972 ALOGE("%s: Camera %d: Unable to delete old output stream "
2973 "for recording: %s (%d)", __FUNCTION__, mCameraId,
2974 strerror(-res), res);
2975 return res;
2976 }
2977 mRecordingStreamId = NO_STREAM;
2978 }
2979 }
2980
2981 if (mRecordingStreamId == NO_STREAM) {
2982 res = mDevice->createStream(mRecordingWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002983 params.videoWidth, params.videoHeight,
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002984 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0, &mRecordingStreamId);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002985 if (res != OK) {
2986 ALOGE("%s: Camera %d: Can't create output stream for recording: "
2987 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2988 return res;
2989 }
2990 }
2991
2992 return OK;
2993}
2994
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002995status_t Camera2Client::updateRequestCommon(camera_metadata_t *request,
2996 const Parameters &params) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002997 ATRACE_CALL();
2998 status_t res;
2999 res = updateEntry(request,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003000 ANDROID_CONTROL_AE_TARGET_FPS_RANGE, params.previewFpsRange, 2);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003001 if (res != OK) return res;
3002
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003003 uint8_t wbMode = params.autoWhiteBalanceLock ?
3004 ANDROID_CONTROL_AWB_LOCKED : params.wbMode;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003005 res = updateEntry(request,
3006 ANDROID_CONTROL_AWB_MODE, &wbMode, 1);
3007 if (res != OK) return res;
3008 res = updateEntry(request,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003009 ANDROID_CONTROL_EFFECT_MODE, &params.effectMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003010 if (res != OK) return res;
3011 res = updateEntry(request,
3012 ANDROID_CONTROL_AE_ANTIBANDING_MODE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003013 &params.antibandingMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003014 if (res != OK) return res;
3015
3016 uint8_t controlMode =
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003017 (params.sceneMode == ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED) ?
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003018 ANDROID_CONTROL_AUTO : ANDROID_CONTROL_USE_SCENE_MODE;
3019 res = updateEntry(request,
3020 ANDROID_CONTROL_MODE, &controlMode, 1);
3021 if (res != OK) return res;
3022 if (controlMode == ANDROID_CONTROL_USE_SCENE_MODE) {
3023 res = updateEntry(request,
3024 ANDROID_CONTROL_SCENE_MODE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003025 &params.sceneMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003026 if (res != OK) return res;
3027 }
3028
3029 uint8_t flashMode = ANDROID_FLASH_OFF;
3030 uint8_t aeMode;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003031 switch (params.flashMode) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003032 case Parameters::FLASH_MODE_OFF:
3033 aeMode = ANDROID_CONTROL_AE_ON; break;
3034 case Parameters::FLASH_MODE_AUTO:
3035 aeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH; break;
3036 case Parameters::FLASH_MODE_ON:
3037 aeMode = ANDROID_CONTROL_AE_ON_ALWAYS_FLASH; break;
3038 case Parameters::FLASH_MODE_TORCH:
3039 aeMode = ANDROID_CONTROL_AE_ON;
3040 flashMode = ANDROID_FLASH_TORCH;
3041 break;
3042 case Parameters::FLASH_MODE_RED_EYE:
3043 aeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE; break;
3044 default:
3045 ALOGE("%s: Camera %d: Unknown flash mode %d", __FUNCTION__,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003046 mCameraId, params.flashMode);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003047 return BAD_VALUE;
3048 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003049 if (params.autoExposureLock) aeMode = ANDROID_CONTROL_AE_LOCKED;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003050
3051 res = updateEntry(request,
3052 ANDROID_FLASH_MODE, &flashMode, 1);
3053 if (res != OK) return res;
3054 res = updateEntry(request,
3055 ANDROID_CONTROL_AE_MODE, &aeMode, 1);
3056 if (res != OK) return res;
3057
3058 float focusDistance = 0; // infinity focus in diopters
3059 uint8_t focusMode;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003060 switch (params.focusMode) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003061 case Parameters::FOCUS_MODE_AUTO:
3062 case Parameters::FOCUS_MODE_MACRO:
3063 case Parameters::FOCUS_MODE_CONTINUOUS_VIDEO:
3064 case Parameters::FOCUS_MODE_CONTINUOUS_PICTURE:
3065 case Parameters::FOCUS_MODE_EDOF:
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003066 focusMode = params.focusMode;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003067 break;
3068 case Parameters::FOCUS_MODE_INFINITY:
3069 case Parameters::FOCUS_MODE_FIXED:
3070 focusMode = ANDROID_CONTROL_AF_OFF;
3071 break;
3072 default:
3073 ALOGE("%s: Camera %d: Unknown focus mode %d", __FUNCTION__,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003074 mCameraId, params.focusMode);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003075 return BAD_VALUE;
3076 }
3077 res = updateEntry(request,
3078 ANDROID_LENS_FOCUS_DISTANCE, &focusDistance, 1);
3079 if (res != OK) return res;
3080 res = updateEntry(request,
3081 ANDROID_CONTROL_AF_MODE, &focusMode, 1);
3082 if (res != OK) return res;
3083
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003084 size_t focusingAreasSize = params.focusingAreas.size() * 5;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003085 int32_t *focusingAreas = new int32_t[focusingAreasSize];
3086 for (size_t i = 0; i < focusingAreasSize; i += 5) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003087 focusingAreas[i + 0] = params.focusingAreas[i].left;
3088 focusingAreas[i + 1] = params.focusingAreas[i].top;
3089 focusingAreas[i + 2] = params.focusingAreas[i].right;
3090 focusingAreas[i + 3] = params.focusingAreas[i].bottom;
3091 focusingAreas[i + 4] = params.focusingAreas[i].weight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003092 }
3093 res = updateEntry(request,
3094 ANDROID_CONTROL_AF_REGIONS, focusingAreas,focusingAreasSize);
3095 if (res != OK) return res;
3096 delete[] focusingAreas;
3097
3098 res = updateEntry(request,
3099 ANDROID_CONTROL_AE_EXP_COMPENSATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003100 &params.exposureCompensation, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003101 if (res != OK) return res;
3102
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003103 size_t meteringAreasSize = params.meteringAreas.size() * 5;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003104 int32_t *meteringAreas = new int32_t[meteringAreasSize];
3105 for (size_t i = 0; i < meteringAreasSize; i += 5) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003106 meteringAreas[i + 0] = params.meteringAreas[i].left;
3107 meteringAreas[i + 1] = params.meteringAreas[i].top;
3108 meteringAreas[i + 2] = params.meteringAreas[i].right;
3109 meteringAreas[i + 3] = params.meteringAreas[i].bottom;
3110 meteringAreas[i + 4] = params.meteringAreas[i].weight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003111 }
3112 res = updateEntry(request,
3113 ANDROID_CONTROL_AE_REGIONS, meteringAreas, meteringAreasSize);
3114 if (res != OK) return res;
3115
3116 res = updateEntry(request,
3117 ANDROID_CONTROL_AWB_REGIONS, meteringAreas, meteringAreasSize);
3118 if (res != OK) return res;
3119 delete[] meteringAreas;
3120
3121 // Need to convert zoom index into a crop rectangle. The rectangle is
3122 // chosen to maximize its area on the sensor
3123
3124 camera_metadata_entry_t maxDigitalZoom =
3125 staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM);
3126 float zoomIncrement = (maxDigitalZoom.data.f[0] - 1) /
3127 (NUM_ZOOM_STEPS-1);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003128 float zoomRatio = 1 + zoomIncrement * params.zoom;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003129
3130 camera_metadata_entry_t activePixelArraySize =
3131 staticInfo(ANDROID_SENSOR_ACTIVE_ARRAY_SIZE, 2, 2);
3132 int32_t arrayWidth = activePixelArraySize.data.i32[0];
3133 int32_t arrayHeight = activePixelArraySize.data.i32[1];
3134 float zoomLeft, zoomTop, zoomWidth, zoomHeight;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003135 if (params.previewWidth >= params.previewHeight) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003136 zoomWidth = arrayWidth / zoomRatio;
3137 zoomHeight = zoomWidth *
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003138 params.previewHeight / params.previewWidth;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003139 } else {
3140 zoomHeight = arrayHeight / zoomRatio;
3141 zoomWidth = zoomHeight *
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003142 params.previewWidth / params.previewHeight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003143 }
3144 zoomLeft = (arrayWidth - zoomWidth) / 2;
3145 zoomTop = (arrayHeight - zoomHeight) / 2;
3146
3147 int32_t cropRegion[3] = { zoomLeft, zoomTop, zoomWidth };
3148 res = updateEntry(request,
3149 ANDROID_SCALER_CROP_REGION, cropRegion, 3);
3150 if (res != OK) return res;
3151
3152 // TODO: Decide how to map recordingHint, or whether just to ignore it
3153
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003154 uint8_t vstabMode = params.videoStabilization ?
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003155 ANDROID_CONTROL_VIDEO_STABILIZATION_ON :
3156 ANDROID_CONTROL_VIDEO_STABILIZATION_OFF;
3157 res = updateEntry(request,
3158 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
3159 &vstabMode, 1);
3160 if (res != OK) return res;
3161
3162 return OK;
3163}
3164
3165status_t Camera2Client::updateEntry(camera_metadata_t *buffer,
3166 uint32_t tag, const void *data, size_t data_count) {
3167 camera_metadata_entry_t entry;
3168 status_t res;
3169 res = find_camera_metadata_entry(buffer, tag, &entry);
3170 if (res == NAME_NOT_FOUND) {
3171 res = add_camera_metadata_entry(buffer,
3172 tag, data, data_count);
3173 } else if (res == OK) {
3174 res = update_camera_metadata_entry(buffer,
3175 entry.index, data, data_count, NULL);
3176 }
3177
3178 if (res != OK) {
3179 ALOGE("%s: Unable to update metadata entry %s.%s (%x): %s (%d)",
3180 __FUNCTION__, get_camera_metadata_section_name(tag),
3181 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
3182 }
3183 return res;
3184}
3185
3186status_t Camera2Client::deleteEntry(camera_metadata_t *buffer, uint32_t tag) {
3187 camera_metadata_entry_t entry;
3188 status_t res;
3189 res = find_camera_metadata_entry(buffer, tag, &entry);
3190 if (res == NAME_NOT_FOUND) {
3191 return OK;
3192 } else if (res != OK) {
3193 ALOGE("%s: Error looking for entry %s.%s (%x): %s %d",
3194 __FUNCTION__,
3195 get_camera_metadata_section_name(tag),
3196 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
3197 return res;
3198 }
3199 res = delete_camera_metadata_entry(buffer, entry.index);
3200 if (res != OK) {
3201 ALOGE("%s: Error deleting entry %s.%s (%x): %s %d",
3202 __FUNCTION__,
3203 get_camera_metadata_section_name(tag),
3204 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
3205 }
3206 return res;
3207}
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003208
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07003209int Camera2Client::formatStringToEnum(const char *format) {
3210 return
3211 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422SP) ?
3212 HAL_PIXEL_FORMAT_YCbCr_422_SP : // NV16
3213 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420SP) ?
3214 HAL_PIXEL_FORMAT_YCrCb_420_SP : // NV21
3215 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422I) ?
3216 HAL_PIXEL_FORMAT_YCbCr_422_I : // YUY2
3217 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420P) ?
3218 HAL_PIXEL_FORMAT_YV12 : // YV12
3219 !strcmp(format, CameraParameters::PIXEL_FORMAT_RGB565) ?
3220 HAL_PIXEL_FORMAT_RGB_565 : // RGB565
3221 !strcmp(format, CameraParameters::PIXEL_FORMAT_RGBA8888) ?
3222 HAL_PIXEL_FORMAT_RGBA_8888 : // RGB8888
3223 !strcmp(format, CameraParameters::PIXEL_FORMAT_BAYER_RGGB) ?
3224 HAL_PIXEL_FORMAT_RAW_SENSOR : // Raw sensor data
3225 -1;
3226}
3227
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003228const char* Camera2Client::formatEnumToString(int format) {
3229 const char *fmt;
3230 switch(format) {
3231 case HAL_PIXEL_FORMAT_YCbCr_422_SP: // NV16
3232 fmt = CameraParameters::PIXEL_FORMAT_YUV422SP;
3233 break;
3234 case HAL_PIXEL_FORMAT_YCrCb_420_SP: // NV21
3235 fmt = CameraParameters::PIXEL_FORMAT_YUV420SP;
3236 break;
3237 case HAL_PIXEL_FORMAT_YCbCr_422_I: // YUY2
3238 fmt = CameraParameters::PIXEL_FORMAT_YUV422I;
3239 break;
3240 case HAL_PIXEL_FORMAT_YV12: // YV12
3241 fmt = CameraParameters::PIXEL_FORMAT_YUV420P;
3242 break;
3243 case HAL_PIXEL_FORMAT_RGB_565: // RGB565
3244 fmt = CameraParameters::PIXEL_FORMAT_RGB565;
3245 break;
3246 case HAL_PIXEL_FORMAT_RGBA_8888: // RGBA8888
3247 fmt = CameraParameters::PIXEL_FORMAT_RGBA8888;
3248 break;
3249 case HAL_PIXEL_FORMAT_RAW_SENSOR:
3250 ALOGW("Raw sensor preview format requested.");
3251 fmt = CameraParameters::PIXEL_FORMAT_BAYER_RGGB;
3252 break;
3253 default:
3254 ALOGE("%s: Unknown preview format: %x",
3255 __FUNCTION__, format);
3256 fmt = NULL;
3257 break;
3258 }
3259 return fmt;
3260}
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07003261
3262int Camera2Client::wbModeStringToEnum(const char *wbMode) {
3263 return
3264 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_AUTO) ?
3265 ANDROID_CONTROL_AWB_AUTO :
3266 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_INCANDESCENT) ?
3267 ANDROID_CONTROL_AWB_INCANDESCENT :
3268 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_FLUORESCENT) ?
3269 ANDROID_CONTROL_AWB_FLUORESCENT :
3270 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT) ?
3271 ANDROID_CONTROL_AWB_WARM_FLUORESCENT :
3272 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_DAYLIGHT) ?
3273 ANDROID_CONTROL_AWB_DAYLIGHT :
3274 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT) ?
3275 ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT :
3276 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_TWILIGHT) ?
3277 ANDROID_CONTROL_AWB_TWILIGHT :
3278 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_SHADE) ?
3279 ANDROID_CONTROL_AWB_SHADE :
3280 -1;
3281}
3282
3283int Camera2Client::effectModeStringToEnum(const char *effectMode) {
3284 return
3285 !strcmp(effectMode, CameraParameters::EFFECT_NONE) ?
3286 ANDROID_CONTROL_EFFECT_OFF :
3287 !strcmp(effectMode, CameraParameters::EFFECT_MONO) ?
3288 ANDROID_CONTROL_EFFECT_MONO :
3289 !strcmp(effectMode, CameraParameters::EFFECT_NEGATIVE) ?
3290 ANDROID_CONTROL_EFFECT_NEGATIVE :
3291 !strcmp(effectMode, CameraParameters::EFFECT_SOLARIZE) ?
3292 ANDROID_CONTROL_EFFECT_SOLARIZE :
3293 !strcmp(effectMode, CameraParameters::EFFECT_SEPIA) ?
3294 ANDROID_CONTROL_EFFECT_SEPIA :
3295 !strcmp(effectMode, CameraParameters::EFFECT_POSTERIZE) ?
3296 ANDROID_CONTROL_EFFECT_POSTERIZE :
3297 !strcmp(effectMode, CameraParameters::EFFECT_WHITEBOARD) ?
3298 ANDROID_CONTROL_EFFECT_WHITEBOARD :
3299 !strcmp(effectMode, CameraParameters::EFFECT_BLACKBOARD) ?
3300 ANDROID_CONTROL_EFFECT_BLACKBOARD :
3301 !strcmp(effectMode, CameraParameters::EFFECT_AQUA) ?
3302 ANDROID_CONTROL_EFFECT_AQUA :
3303 -1;
3304}
3305
3306int Camera2Client::abModeStringToEnum(const char *abMode) {
3307 return
3308 !strcmp(abMode, CameraParameters::ANTIBANDING_AUTO) ?
3309 ANDROID_CONTROL_AE_ANTIBANDING_AUTO :
3310 !strcmp(abMode, CameraParameters::ANTIBANDING_OFF) ?
3311 ANDROID_CONTROL_AE_ANTIBANDING_OFF :
3312 !strcmp(abMode, CameraParameters::ANTIBANDING_50HZ) ?
3313 ANDROID_CONTROL_AE_ANTIBANDING_50HZ :
3314 !strcmp(abMode, CameraParameters::ANTIBANDING_60HZ) ?
3315 ANDROID_CONTROL_AE_ANTIBANDING_60HZ :
3316 -1;
3317}
3318
3319int Camera2Client::sceneModeStringToEnum(const char *sceneMode) {
3320 return
3321 !strcmp(sceneMode, CameraParameters::SCENE_MODE_AUTO) ?
3322 ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED :
3323 !strcmp(sceneMode, CameraParameters::SCENE_MODE_ACTION) ?
3324 ANDROID_CONTROL_SCENE_MODE_ACTION :
3325 !strcmp(sceneMode, CameraParameters::SCENE_MODE_PORTRAIT) ?
3326 ANDROID_CONTROL_SCENE_MODE_PORTRAIT :
3327 !strcmp(sceneMode, CameraParameters::SCENE_MODE_LANDSCAPE) ?
3328 ANDROID_CONTROL_SCENE_MODE_LANDSCAPE :
3329 !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT) ?
3330 ANDROID_CONTROL_SCENE_MODE_NIGHT :
3331 !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT_PORTRAIT) ?
3332 ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT :
3333 !strcmp(sceneMode, CameraParameters::SCENE_MODE_THEATRE) ?
3334 ANDROID_CONTROL_SCENE_MODE_THEATRE :
3335 !strcmp(sceneMode, CameraParameters::SCENE_MODE_BEACH) ?
3336 ANDROID_CONTROL_SCENE_MODE_BEACH :
3337 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SNOW) ?
3338 ANDROID_CONTROL_SCENE_MODE_SNOW :
3339 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SUNSET) ?
3340 ANDROID_CONTROL_SCENE_MODE_SUNSET :
3341 !strcmp(sceneMode, CameraParameters::SCENE_MODE_STEADYPHOTO) ?
3342 ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO :
3343 !strcmp(sceneMode, CameraParameters::SCENE_MODE_FIREWORKS) ?
3344 ANDROID_CONTROL_SCENE_MODE_FIREWORKS :
3345 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SPORTS) ?
3346 ANDROID_CONTROL_SCENE_MODE_SPORTS :
3347 !strcmp(sceneMode, CameraParameters::SCENE_MODE_PARTY) ?
3348 ANDROID_CONTROL_SCENE_MODE_PARTY :
3349 !strcmp(sceneMode, CameraParameters::SCENE_MODE_CANDLELIGHT) ?
3350 ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT :
3351 !strcmp(sceneMode, CameraParameters::SCENE_MODE_BARCODE) ?
3352 ANDROID_CONTROL_SCENE_MODE_BARCODE:
3353 -1;
3354}
3355
3356Camera2Client::Parameters::flashMode_t Camera2Client::flashModeStringToEnum(
3357 const char *flashMode) {
3358 return
3359 !strcmp(flashMode, CameraParameters::FLASH_MODE_OFF) ?
3360 Parameters::FLASH_MODE_OFF :
3361 !strcmp(flashMode, CameraParameters::FLASH_MODE_AUTO) ?
3362 Parameters::FLASH_MODE_AUTO :
3363 !strcmp(flashMode, CameraParameters::FLASH_MODE_ON) ?
3364 Parameters::FLASH_MODE_ON :
3365 !strcmp(flashMode, CameraParameters::FLASH_MODE_RED_EYE) ?
3366 Parameters::FLASH_MODE_RED_EYE :
3367 !strcmp(flashMode, CameraParameters::FLASH_MODE_TORCH) ?
3368 Parameters::FLASH_MODE_TORCH :
3369 Parameters::FLASH_MODE_INVALID;
3370}
3371
3372Camera2Client::Parameters::focusMode_t Camera2Client::focusModeStringToEnum(
3373 const char *focusMode) {
3374 return
3375 !strcmp(focusMode, CameraParameters::FOCUS_MODE_AUTO) ?
3376 Parameters::FOCUS_MODE_AUTO :
3377 !strcmp(focusMode, CameraParameters::FOCUS_MODE_INFINITY) ?
3378 Parameters::FOCUS_MODE_INFINITY :
3379 !strcmp(focusMode, CameraParameters::FOCUS_MODE_MACRO) ?
3380 Parameters::FOCUS_MODE_MACRO :
3381 !strcmp(focusMode, CameraParameters::FOCUS_MODE_FIXED) ?
3382 Parameters::FOCUS_MODE_FIXED :
3383 !strcmp(focusMode, CameraParameters::FOCUS_MODE_EDOF) ?
3384 Parameters::FOCUS_MODE_EDOF :
3385 !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO) ?
3386 Parameters::FOCUS_MODE_CONTINUOUS_VIDEO :
3387 !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE) ?
3388 Parameters::FOCUS_MODE_CONTINUOUS_PICTURE :
3389 Parameters::FOCUS_MODE_INVALID;
3390}
3391
3392status_t Camera2Client::parseAreas(const char *areasCStr,
3393 Vector<Parameters::Area> *areas) {
3394 static const size_t NUM_FIELDS = 5;
3395 areas->clear();
3396 if (areasCStr == NULL) {
3397 // If no key exists, use default (0,0,0,0,0)
3398 areas->push();
3399 return OK;
3400 }
3401 String8 areasStr(areasCStr);
3402 ssize_t areaStart = areasStr.find("(", 0) + 1;
3403 while (areaStart != 0) {
3404 const char* area = areasStr.string() + areaStart;
3405 char *numEnd;
3406 int vals[NUM_FIELDS];
3407 for (size_t i = 0; i < NUM_FIELDS; i++) {
3408 errno = 0;
3409 vals[i] = strtol(area, &numEnd, 10);
3410 if (errno || numEnd == area) return BAD_VALUE;
3411 area = numEnd + 1;
3412 }
3413 areas->push(Parameters::Area(
3414 vals[0], vals[1], vals[2], vals[3], vals[4]) );
3415 areaStart = areasStr.find("(", areaStart) + 1;
3416 }
3417 return OK;
3418}
3419
3420status_t Camera2Client::validateAreas(const Vector<Parameters::Area> &areas,
3421 size_t maxRegions) {
3422 // Definition of valid area can be found in
3423 // include/camera/CameraParameters.h
3424 if (areas.size() == 0) return BAD_VALUE;
3425 if (areas.size() == 1) {
3426 if (areas[0].left == 0 &&
3427 areas[0].top == 0 &&
3428 areas[0].right == 0 &&
3429 areas[0].bottom == 0 &&
3430 areas[0].weight == 0) {
3431 // Single (0,0,0,0,0) entry is always valid (== driver decides)
3432 return OK;
3433 }
3434 }
3435 if (areas.size() > maxRegions) {
3436 ALOGE("%s: Too many areas requested: %d",
3437 __FUNCTION__, areas.size());
3438 return BAD_VALUE;
3439 }
3440
3441 for (Vector<Parameters::Area>::const_iterator a = areas.begin();
3442 a != areas.end(); a++) {
3443 if (a->weight < 1 || a->weight > 1000) return BAD_VALUE;
3444 if (a->left < -1000 || a->left > 1000) return BAD_VALUE;
3445 if (a->top < -1000 || a->top > 1000) return BAD_VALUE;
3446 if (a->right < -1000 || a->right > 1000) return BAD_VALUE;
3447 if (a->bottom < -1000 || a->bottom > 1000) return BAD_VALUE;
3448 if (a->left >= a->right) return BAD_VALUE;
3449 if (a->top >= a->bottom) return BAD_VALUE;
3450 }
3451 return OK;
3452}
3453
3454bool Camera2Client::boolFromString(const char *boolStr) {
3455 return !boolStr ? false :
3456 !strcmp(boolStr, CameraParameters::TRUE) ? true :
3457 false;
3458}
3459
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07003460int Camera2Client::degToTransform(int degrees, bool mirror) {
3461 if (!mirror) {
3462 if (degrees == 0) return 0;
3463 else if (degrees == 90) return HAL_TRANSFORM_ROT_90;
3464 else if (degrees == 180) return HAL_TRANSFORM_ROT_180;
3465 else if (degrees == 270) return HAL_TRANSFORM_ROT_270;
3466 } else { // Do mirror (horizontal flip)
3467 if (degrees == 0) { // FLIP_H and ROT_0
3468 return HAL_TRANSFORM_FLIP_H;
3469 } else if (degrees == 90) { // FLIP_H and ROT_90
3470 return HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90;
3471 } else if (degrees == 180) { // FLIP_H and ROT_180
3472 return HAL_TRANSFORM_FLIP_V;
3473 } else if (degrees == 270) { // FLIP_H and ROT_270
3474 return HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90;
3475 }
3476 }
3477 ALOGE("%s: Bad input: %d", __FUNCTION__, degrees);
3478 return -1;
3479}
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07003480
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07003481} // namespace android