blob: 0d45596a066efedde444a0016a39173d751da401 [file] [log] [blame]
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "Camera2Client"
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070018#define ATRACE_TAG ATRACE_TAG_CAMERA
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070019//#define LOG_NDEBUG 0
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070020
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070021#include <utils/Log.h>
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070022#include <utils/Trace.h>
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070023
24#include <cutils/properties.h>
25#include <gui/SurfaceTextureClient.h>
26#include <gui/Surface.h>
Eino-Ville Talvala78822d72012-07-18 17:52:18 -070027#include <media/hardware/MetadataBufferType.h>
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070028
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070029#include <math.h>
30
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070031#include "Camera2Client.h"
32
33namespace android {
34
35#define ALOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__);
36#define ALOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__);
37
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070038static int getCallingPid() {
39 return IPCThreadState::self()->getCallingPid();
40}
41
42static int getCallingUid() {
43 return IPCThreadState::self()->getCallingUid();
44}
45
46// Interface used by CameraService
47
48Camera2Client::Camera2Client(const sp<CameraService>& cameraService,
49 const sp<ICameraClient>& cameraClient,
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070050 int cameraId,
51 int cameraFacing,
52 int clientPid):
53 Client(cameraService, cameraClient,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070054 cameraId, cameraFacing, clientPid),
Eino-Ville Talvala3a609142012-07-31 14:36:26 -070055 mState(DISCONNECTED),
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -070056 mPreviewStreamId(NO_STREAM),
57 mPreviewRequest(NULL),
58 mCaptureStreamId(NO_STREAM),
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -070059 mCaptureRequest(NULL),
60 mRecordingStreamId(NO_STREAM),
James Dong983cf232012-08-01 16:39:55 -070061 mRecordingRequest(NULL),
62 mRecordingHeapCount(kDefaultRecordingHeapCount)
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070063{
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070064 ATRACE_CALL();
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070065
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070066 mDevice = new Camera2Device(cameraId);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070067}
68
Eino-Ville Talvala3a609142012-07-31 14:36:26 -070069status_t Camera2Client::checkPid(const char* checkLocation) const {
70 int callingPid = getCallingPid();
71 if (callingPid == mClientPid) return NO_ERROR;
72
73 ALOGE("%s: attempt to use a locked camera from a different process"
74 " (old pid %d, new pid %d)", checkLocation, mClientPid, callingPid);
75 return PERMISSION_DENIED;
76}
77
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070078status_t Camera2Client::initialize(camera_module_t *module)
79{
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070080 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -070081 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070082 status_t res;
83
84 res = mDevice->initialize(module);
85 if (res != OK) {
86 ALOGE("%s: Camera %d: unable to initialize device: %s (%d)",
87 __FUNCTION__, mCameraId, strerror(-res), res);
88 return NO_INIT;
89 }
90
91 res = buildDefaultParameters();
92 if (res != OK) {
93 ALOGE("%s: Camera %d: unable to build defaults: %s (%d)",
94 __FUNCTION__, mCameraId, strerror(-res), res);
95 return NO_INIT;
96 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -070097
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070098 if (gLogLevel >= 1) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -070099 LockedParameters::Key k(mParameters);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700100 ALOGD("%s: Default parameters converted from camera %d:", __FUNCTION__,
101 mCameraId);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700102 ALOGD("%s", k.mParameters.paramsFlattened.string());
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700103 }
104
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700105 mState = STOPPED;
106
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700107 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700108}
109
110Camera2Client::~Camera2Client() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700111 ATRACE_CALL();
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700112 ALOGV("%s: Camera %d: Shutting down", __FUNCTION__, mCameraId);
113
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700114 mDestructionStarted = true;
115
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700116 // Rewrite mClientPid to allow shutdown by CameraService
117 mClientPid = getCallingPid();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700118 disconnect();
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -0700119
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700120}
121
122status_t Camera2Client::dump(int fd, const Vector<String16>& args) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700123 String8 result;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700124 result.appendFormat("Client2[%d] (%p) PID: %d, dump:\n",
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700125 mCameraId,
126 getCameraClient()->asBinder().get(),
127 mClientPid);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700128 result.append(" State: ");
129#define CASE_APPEND_ENUM(x) case x: result.append(#x "\n"); break;
130
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700131 const Parameters& p = mParameters.unsafeUnlock();
132
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700133 result.append(getStateName(mState));
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700134
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700135 result.append("\n Current parameters:\n");
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700136 result.appendFormat(" Preview size: %d x %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700137 p.previewWidth, p.previewHeight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700138 result.appendFormat(" Preview FPS range: %d - %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700139 p.previewFpsRange[0], p.previewFpsRange[1]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700140 result.appendFormat(" Preview HAL pixel format: 0x%x\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700141 p.previewFormat);
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700142 result.appendFormat(" Preview transform: %x\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700143 p.previewTransform);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700144 result.appendFormat(" Picture size: %d x %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700145 p.pictureWidth, p.pictureHeight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700146 result.appendFormat(" Jpeg thumbnail size: %d x %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700147 p.jpegThumbSize[0], p.jpegThumbSize[1]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700148 result.appendFormat(" Jpeg quality: %d, thumbnail quality: %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700149 p.jpegQuality, p.jpegThumbQuality);
150 result.appendFormat(" Jpeg rotation: %d\n", p.jpegRotation);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700151 result.appendFormat(" GPS tags %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700152 p.gpsEnabled ? "enabled" : "disabled");
153 if (p.gpsEnabled) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700154 result.appendFormat(" GPS lat x long x alt: %f x %f x %f\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700155 p.gpsCoordinates[0], p.gpsCoordinates[1],
156 p.gpsCoordinates[2]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700157 result.appendFormat(" GPS timestamp: %lld\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700158 p.gpsTimestamp);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700159 result.appendFormat(" GPS processing method: %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700160 p.gpsProcessingMethod.string());
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700161 }
162
163 result.append(" White balance mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700164 switch (p.wbMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700165 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_AUTO)
166 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_INCANDESCENT)
167 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_FLUORESCENT)
168 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_WARM_FLUORESCENT)
169 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_DAYLIGHT)
170 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT)
171 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_TWILIGHT)
172 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_SHADE)
173 default: result.append("UNKNOWN\n");
174 }
175
176 result.append(" Effect mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700177 switch (p.effectMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700178 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_OFF)
179 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_MONO)
180 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_NEGATIVE)
181 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_SOLARIZE)
182 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_SEPIA)
183 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_POSTERIZE)
184 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_WHITEBOARD)
185 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_BLACKBOARD)
186 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_AQUA)
187 default: result.append("UNKNOWN\n");
188 }
189
190 result.append(" Antibanding mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700191 switch (p.antibandingMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700192 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_AUTO)
193 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_OFF)
194 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_50HZ)
195 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_60HZ)
196 default: result.append("UNKNOWN\n");
197 }
198
199 result.append(" Scene mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700200 switch (p.sceneMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700201 case ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED:
202 result.append("AUTO\n"); break;
203 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_ACTION)
204 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_PORTRAIT)
205 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_LANDSCAPE)
206 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_NIGHT)
207 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT)
208 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_THEATRE)
209 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_BEACH)
210 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SNOW)
211 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SUNSET)
212 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO)
213 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_FIREWORKS)
214 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SPORTS)
215 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_PARTY)
216 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT)
217 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_BARCODE)
218 default: result.append("UNKNOWN\n");
219 }
220
221 result.append(" Flash mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700222 switch (p.flashMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700223 CASE_APPEND_ENUM(Parameters::FLASH_MODE_OFF)
224 CASE_APPEND_ENUM(Parameters::FLASH_MODE_AUTO)
225 CASE_APPEND_ENUM(Parameters::FLASH_MODE_ON)
226 CASE_APPEND_ENUM(Parameters::FLASH_MODE_TORCH)
227 CASE_APPEND_ENUM(Parameters::FLASH_MODE_RED_EYE)
228 CASE_APPEND_ENUM(Parameters::FLASH_MODE_INVALID)
229 default: result.append("UNKNOWN\n");
230 }
231
232 result.append(" Focus mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700233 switch (p.focusMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700234 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_AUTO)
235 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_MACRO)
236 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_CONTINUOUS_VIDEO)
237 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_CONTINUOUS_PICTURE)
238 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_EDOF)
239 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_INFINITY)
240 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_FIXED)
241 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_INVALID)
242 default: result.append("UNKNOWN\n");
243 }
244
245 result.append(" Focusing areas:\n");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700246 for (size_t i = 0; i < p.focusingAreas.size(); i++) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700247 result.appendFormat(" [ (%d, %d, %d, %d), weight %d ]\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700248 p.focusingAreas[i].left,
249 p.focusingAreas[i].top,
250 p.focusingAreas[i].right,
251 p.focusingAreas[i].bottom,
252 p.focusingAreas[i].weight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700253 }
254
255 result.appendFormat(" Exposure compensation index: %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700256 p.exposureCompensation);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700257
258 result.appendFormat(" AE lock %s, AWB lock %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700259 p.autoExposureLock ? "enabled" : "disabled",
260 p.autoWhiteBalanceLock ? "enabled" : "disabled" );
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700261
262 result.appendFormat(" Metering areas:\n");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700263 for (size_t i = 0; i < p.meteringAreas.size(); i++) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700264 result.appendFormat(" [ (%d, %d, %d, %d), weight %d ]\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700265 p.meteringAreas[i].left,
266 p.meteringAreas[i].top,
267 p.meteringAreas[i].right,
268 p.meteringAreas[i].bottom,
269 p.meteringAreas[i].weight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700270 }
271
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700272 result.appendFormat(" Zoom index: %d\n", p.zoom);
273 result.appendFormat(" Video size: %d x %d\n", p.videoWidth,
274 p.videoHeight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700275
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700276 result.appendFormat(" Recording hint is %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700277 p.recordingHint ? "set" : "not set");
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700278
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700279 result.appendFormat(" Video stabilization is %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700280 p.videoStabilization ? "enabled" : "disabled");
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700281
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700282 result.append(" Current streams:\n");
283 result.appendFormat(" Preview stream ID: %d\n", mPreviewStreamId);
284 result.appendFormat(" Capture stream ID: %d\n", mCaptureStreamId);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700285 result.appendFormat(" Recording stream ID: %d\n", mRecordingStreamId);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700286
287 result.append(" Current requests:\n");
288 if (mPreviewRequest != NULL) {
289 result.append(" Preview request:\n");
290 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700291 dump_indented_camera_metadata(mPreviewRequest, fd, 2, 6);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700292 } else {
293 result.append(" Preview request: undefined\n");
294 write(fd, result.string(), result.size());
295 }
296
297 if (mCaptureRequest != NULL) {
298 result = " Capture request:\n";
299 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700300 dump_indented_camera_metadata(mCaptureRequest, fd, 2, 6);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700301 } else {
302 result = " Capture request: undefined\n";
303 write(fd, result.string(), result.size());
304 }
305
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700306 if (mRecordingRequest != NULL) {
307 result = " Recording request:\n";
308 write(fd, result.string(), result.size());
309 dump_indented_camera_metadata(mRecordingRequest, fd, 2, 6);
310 } else {
311 result = " Recording request: undefined\n";
312 write(fd, result.string(), result.size());
313 }
314
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700315 result = " Device dump:\n";
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700316 write(fd, result.string(), result.size());
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700317
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700318 status_t res = mDevice->dump(fd, args);
319 if (res != OK) {
320 result = String8::format(" Error dumping device: %s (%d)",
321 strerror(-res), res);
322 write(fd, result.string(), result.size());
323 }
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700324
325#undef CASE_APPEND_ENUM
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700326 return NO_ERROR;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700327}
328
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700329const char* Camera2Client::getStateName(State state) {
330#define CASE_ENUM_TO_CHAR(x) case x: return(#x); break;
331 switch(state) {
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700332 CASE_ENUM_TO_CHAR(DISCONNECTED)
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700333 CASE_ENUM_TO_CHAR(STOPPED)
334 CASE_ENUM_TO_CHAR(WAITING_FOR_PREVIEW_WINDOW)
335 CASE_ENUM_TO_CHAR(PREVIEW)
336 CASE_ENUM_TO_CHAR(RECORD)
337 CASE_ENUM_TO_CHAR(STILL_CAPTURE)
338 CASE_ENUM_TO_CHAR(VIDEO_SNAPSHOT)
339 default:
340 return "Unknown state!";
341 break;
342 }
343#undef CASE_ENUM_TO_CHAR
344}
345
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700346// ICamera interface
347
348void Camera2Client::disconnect() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700349 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700350 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700351 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700352 status_t res;
353 if ( (res = checkPid(__FUNCTION__) ) != OK) return;
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700354
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700355 if (mDevice == 0) return;
356
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700357 stopPreviewL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700358
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700359 mDevice->waitUntilDrained();
360
361 if (mPreviewStreamId != NO_STREAM) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700362 mDevice->deleteStream(mPreviewStreamId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700363 mPreviewStreamId = NO_STREAM;
364 }
365
366 if (mCaptureStreamId != NO_STREAM) {
367 mDevice->deleteStream(mCaptureStreamId);
368 mCaptureStreamId = NO_STREAM;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700369 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700370
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -0700371 if (mRecordingStreamId != NO_STREAM) {
372 mDevice->deleteStream(mRecordingStreamId);
373 mRecordingStreamId = NO_STREAM;
374 }
375
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700376 mDevice.clear();
377 mState = DISCONNECTED;
378
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700379 CameraService::Client::disconnect();
380}
381
382status_t Camera2Client::connect(const sp<ICameraClient>& client) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700383 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700384 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700385 Mutex::Autolock icl(mICameraLock);
386
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700387 if (mClientPid != 0 && getCallingPid() != mClientPid) {
388 ALOGE("%s: Camera %d: Connection attempt from pid %d; "
389 "current locked to pid %d", __FUNCTION__,
390 mCameraId, getCallingPid(), mClientPid);
391 return BAD_VALUE;
392 }
393
394 mClientPid = getCallingPid();
395 mCameraClient = client;
396
397 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700398}
399
400status_t Camera2Client::lock() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700401 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700402 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700403 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700404 ALOGV("%s: Camera %d: Lock call from pid %d; current client pid %d",
405 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700406
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700407 if (mClientPid == 0) {
408 mClientPid = getCallingPid();
409 return OK;
410 }
411
412 if (mClientPid != getCallingPid()) {
413 ALOGE("%s: Camera %d: Lock call from pid %d; currently locked to pid %d",
414 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
415 return EBUSY;
416 }
417
418 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700419}
420
421status_t Camera2Client::unlock() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700422 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700423 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700424 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700425 ALOGV("%s: Camera %d: Unlock call from pid %d; current client pid %d",
426 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700427
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700428 // TODO: Check for uninterruptable conditions
429
430 if (mClientPid == getCallingPid()) {
431 mClientPid = 0;
432 mCameraClient.clear();
433 return OK;
434 }
435
436 ALOGE("%s: Camera %d: Unlock call from pid %d; currently locked to pid %d",
437 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
438 return EBUSY;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700439}
440
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700441status_t Camera2Client::setPreviewDisplay(
442 const sp<Surface>& surface) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700443 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700444 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700445 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700446 status_t res;
447 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700448
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700449 sp<IBinder> binder;
450 sp<ANativeWindow> window;
451 if (surface != 0) {
452 binder = surface->asBinder();
453 window = surface;
454 }
455
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700456 return setPreviewWindowL(binder,window);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700457}
458
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700459status_t Camera2Client::setPreviewTexture(
460 const sp<ISurfaceTexture>& surfaceTexture) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700461 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700462 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700463 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700464 status_t res;
465 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700466
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700467 sp<IBinder> binder;
468 sp<ANativeWindow> window;
469 if (surfaceTexture != 0) {
470 binder = surfaceTexture->asBinder();
471 window = new SurfaceTextureClient(surfaceTexture);
472 }
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700473 return setPreviewWindowL(binder, window);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700474}
475
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700476status_t Camera2Client::setPreviewWindowL(const sp<IBinder>& binder,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700477 sp<ANativeWindow> window) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700478 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700479 status_t res;
480
481 if (binder == mPreviewSurface) {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700482 ALOGV("%s: Camera %d: New window is same as old window",
483 __FUNCTION__, mCameraId);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700484 return NO_ERROR;
485 }
486
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700487 switch (mState) {
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700488 case DISCONNECTED:
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700489 case RECORD:
490 case STILL_CAPTURE:
491 case VIDEO_SNAPSHOT:
492 ALOGE("%s: Camera %d: Cannot set preview display while in state %s",
493 __FUNCTION__, mCameraId, getStateName(mState));
494 return INVALID_OPERATION;
495 case STOPPED:
496 case WAITING_FOR_PREVIEW_WINDOW:
497 // OK
498 break;
499 case PREVIEW:
500 // Already running preview - need to stop and create a new stream
501 // TODO: Optimize this so that we don't wait for old stream to drain
502 // before spinning up new stream
503 mDevice->setStreamingRequest(NULL);
504 mState = WAITING_FOR_PREVIEW_WINDOW;
505 break;
506 }
507
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700508 if (mPreviewStreamId != NO_STREAM) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700509 res = mDevice->waitUntilDrained();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700510 if (res != OK) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700511 ALOGE("%s: Error waiting for preview to drain: %s (%d)",
512 __FUNCTION__, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700513 return res;
514 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700515 res = mDevice->deleteStream(mPreviewStreamId);
516 if (res != OK) {
517 ALOGE("%s: Unable to delete old preview stream: %s (%d)",
518 __FUNCTION__, strerror(-res), res);
519 return res;
520 }
521 mPreviewStreamId = NO_STREAM;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700522 }
523
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700524 mPreviewSurface = binder;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700525 mPreviewWindow = window;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700526
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700527 if (mState == WAITING_FOR_PREVIEW_WINDOW) {
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700528 return startPreviewL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700529 }
530
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700531 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700532}
533
534void Camera2Client::setPreviewCallbackFlag(int flag) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700535 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700536 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700537 status_t res;
538 if ( (res = checkPid(__FUNCTION__) ) != OK) return;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700539}
540
541status_t Camera2Client::startPreview() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700542 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700543 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700544 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700545 status_t res;
546 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700547 return startPreviewL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700548}
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700549
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700550status_t Camera2Client::startPreviewL() {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700551 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700552 status_t res;
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700553 if (mState >= PREVIEW) {
554 ALOGE("%s: Can't start preview in state %s",
555 __FUNCTION__, getStateName(mState));
556 return INVALID_OPERATION;
557 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700558
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700559 if (mPreviewWindow == 0) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700560 mState = WAITING_FOR_PREVIEW_WINDOW;
561 return OK;
562 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700563 mState = STOPPED;
564
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700565 LockedParameters::Key k(mParameters);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700566
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700567 res = updatePreviewStream(k.mParameters);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700568 if (res != OK) {
569 ALOGE("%s: Camera %d: Unable to update preview stream: %s (%d)",
570 __FUNCTION__, mCameraId, strerror(-res), res);
571 return res;
572 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700573
574 if (mPreviewRequest == NULL) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700575 res = updatePreviewRequest(k.mParameters);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700576 if (res != OK) {
577 ALOGE("%s: Camera %d: Unable to create preview request: %s (%d)",
578 __FUNCTION__, mCameraId, strerror(-res), res);
579 return res;
580 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700581 }
582
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700583 res = updateEntry(mPreviewRequest,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700584 ANDROID_REQUEST_OUTPUT_STREAMS,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700585 &mPreviewStreamId, 1);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700586 if (res != OK) {
587 ALOGE("%s: Camera %d: Unable to set up preview request: %s (%d)",
588 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700589 return res;
590 }
591 res = sort_camera_metadata(mPreviewRequest);
592 if (res != OK) {
593 ALOGE("%s: Camera %d: Error sorting preview request: %s (%d)",
594 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700595 return res;
596 }
597
598 res = mDevice->setStreamingRequest(mPreviewRequest);
599 if (res != OK) {
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700600 ALOGE("%s: Camera %d: Unable to set preview request to start preview: "
601 "%s (%d)",
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700602 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700603 return res;
604 }
605 mState = PREVIEW;
606
607 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700608}
609
610void Camera2Client::stopPreview() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700611 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700612 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700613 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700614 status_t res;
615 if ( (res = checkPid(__FUNCTION__) ) != OK) return;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700616 stopPreviewL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700617}
618
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700619void Camera2Client::stopPreviewL() {
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700620 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700621 switch (mState) {
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700622 case DISCONNECTED:
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700623 ALOGE("%s: Camera %d: Call before initialized",
624 __FUNCTION__, mCameraId);
625 break;
626 case STOPPED:
627 break;
628 case STILL_CAPTURE:
629 ALOGE("%s: Camera %d: Cannot stop preview during still capture.",
630 __FUNCTION__, mCameraId);
631 break;
632 case RECORD:
633 // TODO: Handle record stop here
634 case PREVIEW:
635 mDevice->setStreamingRequest(NULL);
Eino-Ville Talvala22671062012-07-20 18:30:37 -0700636 mDevice->waitUntilDrained();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700637 case WAITING_FOR_PREVIEW_WINDOW:
638 mState = STOPPED;
639 break;
640 default:
641 ALOGE("%s: Camera %d: Unknown state %d", __FUNCTION__, mCameraId,
642 mState);
643 }
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700644}
645
646bool Camera2Client::previewEnabled() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700647 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700648 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700649 status_t res;
650 if ( (res = checkPid(__FUNCTION__) ) != OK) return false;
651
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700652 return mState == PREVIEW;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700653}
654
655status_t Camera2Client::storeMetaDataInBuffers(bool enabled) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700656 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700657 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700658 status_t res;
659 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
660
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700661 switch (mState) {
662 case RECORD:
663 case VIDEO_SNAPSHOT:
664 ALOGE("%s: Camera %d: Can't be called in state %s",
665 __FUNCTION__, mCameraId, getStateName(mState));
666 return INVALID_OPERATION;
667 default:
668 // OK
669 break;
670 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700671 LockedParameters::Key k(mParameters);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700672
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700673 k.mParameters.storeMetadataInBuffers = enabled;
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700674
675 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700676}
677
678status_t Camera2Client::startRecording() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700679 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700680 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700681 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700682 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700683 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
684
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700685 switch (mState) {
686 case STOPPED:
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700687 res = startPreviewL();
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700688 if (res != OK) return res;
689 break;
690 case PREVIEW:
691 // Ready to go
692 break;
693 case RECORD:
694 case VIDEO_SNAPSHOT:
695 // OK to call this when recording is already on
696 return OK;
697 break;
698 default:
699 ALOGE("%s: Camera %d: Can't start recording in state %s",
700 __FUNCTION__, mCameraId, getStateName(mState));
701 return INVALID_OPERATION;
702 };
703
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700704 LockedParameters::Key k(mParameters);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700705
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700706 if (!k.mParameters.storeMetadataInBuffers) {
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700707 ALOGE("%s: Camera %d: Recording only supported in metadata mode, but "
708 "non-metadata recording mode requested!", __FUNCTION__,
709 mCameraId);
710 return INVALID_OPERATION;
711 }
712
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700713 res = updateRecordingStream(k.mParameters);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700714 if (res != OK) {
715 ALOGE("%s: Camera %d: Unable to update recording stream: %s (%d)",
716 __FUNCTION__, mCameraId, strerror(-res), res);
717 return res;
718 }
719
720 if (mRecordingRequest == NULL) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700721 res = updateRecordingRequest(k.mParameters);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700722 if (res != OK) {
723 ALOGE("%s: Camera %d: Unable to create recording request: %s (%d)",
724 __FUNCTION__, mCameraId, strerror(-res), res);
725 return res;
726 }
727 }
728
729 uint8_t outputStreams[2] = { mPreviewStreamId, mRecordingStreamId };
730 res = updateEntry(mRecordingRequest,
731 ANDROID_REQUEST_OUTPUT_STREAMS,
732 outputStreams, 2);
733 if (res != OK) {
734 ALOGE("%s: Camera %d: Unable to set up recording request: %s (%d)",
735 __FUNCTION__, mCameraId, strerror(-res), res);
736 return res;
737 }
738 res = sort_camera_metadata(mRecordingRequest);
739 if (res != OK) {
740 ALOGE("%s: Camera %d: Error sorting recording request: %s (%d)",
741 __FUNCTION__, mCameraId, strerror(-res), res);
742 return res;
743 }
744
745 res = mDevice->setStreamingRequest(mRecordingRequest);
746 if (res != OK) {
747 ALOGE("%s: Camera %d: Unable to set recording request to start "
748 "recording: %s (%d)", __FUNCTION__, mCameraId,
749 strerror(-res), res);
750 return res;
751 }
752 mState = RECORD;
753
754 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700755}
756
757void Camera2Client::stopRecording() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700758 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700759 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700760 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700761 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700762 if ( (res = checkPid(__FUNCTION__) ) != OK) return;
763
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700764 switch (mState) {
765 case RECORD:
766 // OK to stop
767 break;
768 case STOPPED:
769 case PREVIEW:
770 case STILL_CAPTURE:
771 case VIDEO_SNAPSHOT:
772 default:
773 ALOGE("%s: Camera %d: Can't stop recording in state %s",
774 __FUNCTION__, mCameraId, getStateName(mState));
775 return;
776 };
777
778 // Back to preview. Since record can only be reached through preview,
779 // all preview stream setup should be up to date.
780 res = mDevice->setStreamingRequest(mPreviewRequest);
781 if (res != OK) {
782 ALOGE("%s: Camera %d: Unable to switch back to preview request: "
783 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
784 return;
785 }
786
787 // TODO: Should recording heap be freed? Can't do it yet since requests
788 // could still be in flight.
789
790 mState = PREVIEW;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700791}
792
793bool Camera2Client::recordingEnabled() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700794 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700795 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700796 if ( checkPid(__FUNCTION__) != OK) return false;
797
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700798 return (mState == RECORD || mState == VIDEO_SNAPSHOT);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700799}
800
801void Camera2Client::releaseRecordingFrame(const sp<IMemory>& mem) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700802 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700803 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700804 status_t res;
805 if ( checkPid(__FUNCTION__) != OK) return;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700806 // Make sure this is for the current heap
807 ssize_t offset;
808 size_t size;
809 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
810 if (heap->getHeapID() != mRecordingHeap->mHeap->getHeapID()) {
811 ALOGW("%s: Camera %d: Mismatched heap ID, ignoring release "
812 "(got %x, expected %x)", __FUNCTION__, mCameraId,
813 heap->getHeapID(), mRecordingHeap->mHeap->getHeapID());
814 return;
815 }
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700816 uint8_t *data = (uint8_t*)heap->getBase() + offset;
817 uint32_t type = *(uint32_t*)data;
818 if (type != kMetadataBufferTypeGrallocSource) {
819 ALOGE("%s: Camera %d: Recording frame type invalid (got %x, expected %x)",
820 __FUNCTION__, mCameraId, type, kMetadataBufferTypeGrallocSource);
821 return;
822 }
823 buffer_handle_t imgBuffer = *(buffer_handle_t*)(data + 4);
824 ALOGV("%s: Camera %d: Freeing buffer_handle_t %p", __FUNCTION__, mCameraId,
Eino-Ville Talvala803cbf62012-07-25 15:23:36 -0700825 imgBuffer);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700826 res = mRecordingConsumer->freeBuffer(imgBuffer);
827 if (res != OK) {
828 ALOGE("%s: Camera %d: Unable to free recording frame (buffer_handle_t: %p):"
829 "%s (%d)",
830 __FUNCTION__, mCameraId, imgBuffer, strerror(-res), res);
831 return;
832 }
833
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700834 mRecordingHeapFree++;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700835}
836
837status_t Camera2Client::autoFocus() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700838 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700839 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700840 status_t res;
841 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
842
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700843 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700844}
845
846status_t Camera2Client::cancelAutoFocus() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700847 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700848 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700849 status_t res;
850 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
851
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700852 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700853}
854
855status_t Camera2Client::takePicture(int msgType) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700856 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700857 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700858 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700859 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700860
861 switch (mState) {
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700862 case DISCONNECTED:
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700863 case STOPPED:
864 case WAITING_FOR_PREVIEW_WINDOW:
865 ALOGE("%s: Camera %d: Cannot take picture without preview enabled",
866 __FUNCTION__, mCameraId);
867 return INVALID_OPERATION;
868 case PREVIEW:
869 case RECORD:
870 // Good to go for takePicture
871 break;
872 case STILL_CAPTURE:
873 case VIDEO_SNAPSHOT:
874 ALOGE("%s: Camera %d: Already taking a picture",
875 __FUNCTION__, mCameraId);
876 return INVALID_OPERATION;
877 }
878
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700879 LockedParameters::Key k(mParameters);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700880
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700881 res = updateCaptureStream(k.mParameters);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700882 if (res != OK) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700883 ALOGE("%s: Camera %d: Can't set up still image stream: %s (%d)",
884 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700885 return res;
886 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700887
888 if (mCaptureRequest == NULL) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700889 res = updateCaptureRequest(k.mParameters);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700890 if (res != OK) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700891 ALOGE("%s: Camera %d: Can't create still image capture request: "
892 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700893 return res;
894 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700895 }
896
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700897 camera_metadata_entry_t outputStreams;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700898 if (mState == PREVIEW) {
899 uint8_t streamIds[2] = { mPreviewStreamId, mCaptureStreamId };
900 res = updateEntry(mCaptureRequest, ANDROID_REQUEST_OUTPUT_STREAMS,
901 &streamIds, 2);
902 } else if (mState == RECORD) {
903 uint8_t streamIds[3] = { mPreviewStreamId, mRecordingStreamId,
904 mCaptureStreamId };
905 res = updateEntry(mCaptureRequest, ANDROID_REQUEST_OUTPUT_STREAMS,
906 &streamIds, 3);
907 }
908
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700909 if (res != OK) {
910 ALOGE("%s: Camera %d: Unable to set up still image capture request: "
911 "%s (%d)",
912 __FUNCTION__, mCameraId, strerror(-res), res);
913 return res;
914 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700915 res = sort_camera_metadata(mCaptureRequest);
916 if (res != OK) {
917 ALOGE("%s: Camera %d: Unable to sort capture request: %s (%d)",
918 __FUNCTION__, mCameraId, strerror(-res), res);
919 return res;
920 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700921
922 camera_metadata_t *captureCopy = clone_camera_metadata(mCaptureRequest);
923 if (captureCopy == NULL) {
924 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device",
925 __FUNCTION__, mCameraId);
926 return NO_MEMORY;
927 }
928
929 if (mState == PREVIEW) {
930 res = mDevice->setStreamingRequest(NULL);
931 if (res != OK) {
932 ALOGE("%s: Camera %d: Unable to stop preview for still capture: "
933 "%s (%d)",
934 __FUNCTION__, mCameraId, strerror(-res), res);
935 return res;
936 }
937 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700938 // TODO: Capture should be atomic with setStreamingRequest here
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700939 res = mDevice->capture(captureCopy);
940 if (res != OK) {
941 ALOGE("%s: Camera %d: Unable to submit still image capture request: "
942 "%s (%d)",
943 __FUNCTION__, mCameraId, strerror(-res), res);
944 return res;
945 }
946
947 switch (mState) {
948 case PREVIEW:
949 mState = STILL_CAPTURE;
950 break;
951 case RECORD:
952 mState = VIDEO_SNAPSHOT;
953 break;
954 default:
955 ALOGE("%s: Camera %d: Unknown state for still capture!",
956 __FUNCTION__, mCameraId);
957 return INVALID_OPERATION;
958 }
959
960 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700961}
962
963status_t Camera2Client::setParameters(const String8& params) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700964 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700965 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700966 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700967 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700968 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
969
970 LockedParameters::Key k(mParameters);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700971
972 CameraParameters newParams(params);
973
974 // TODO: Currently ignoring any changes to supposedly read-only
975 // parameters such as supported preview sizes, etc. Should probably
976 // produce an error if they're changed.
977
978 /** Extract and verify new parameters */
979
980 size_t i;
981
982 // PREVIEW_SIZE
983 int previewWidth, previewHeight;
984 newParams.getPreviewSize(&previewWidth, &previewHeight);
985
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700986 if (previewWidth != k.mParameters.previewWidth ||
987 previewHeight != k.mParameters.previewHeight) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700988 if (mState >= PREVIEW) {
989 ALOGE("%s: Preview size cannot be updated when preview "
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700990 "is active! (Currently %d x %d, requested %d x %d",
991 __FUNCTION__,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700992 k.mParameters.previewWidth, k.mParameters.previewHeight,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700993 previewWidth, previewHeight);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700994 return BAD_VALUE;
995 }
996 camera_metadata_entry_t availablePreviewSizes =
997 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
998 for (i = 0; i < availablePreviewSizes.count; i += 2 ) {
999 if (availablePreviewSizes.data.i32[i] == previewWidth &&
1000 availablePreviewSizes.data.i32[i+1] == previewHeight) break;
1001 }
1002 if (i == availablePreviewSizes.count) {
1003 ALOGE("%s: Requested preview size %d x %d is not supported",
1004 __FUNCTION__, previewWidth, previewHeight);
1005 return BAD_VALUE;
1006 }
1007 }
1008
1009 // PREVIEW_FPS_RANGE
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001010 int previewFpsRange[2];
1011 int previewFps = 0;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001012 bool fpsRangeChanged = false;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001013 newParams.getPreviewFpsRange(&previewFpsRange[0], &previewFpsRange[1]);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001014 if (previewFpsRange[0] != k.mParameters.previewFpsRange[0] ||
1015 previewFpsRange[1] != k.mParameters.previewFpsRange[1]) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001016 fpsRangeChanged = true;
1017 camera_metadata_entry_t availablePreviewFpsRanges =
1018 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
1019 for (i = 0; i < availablePreviewFpsRanges.count; i += 2) {
1020 if ((availablePreviewFpsRanges.data.i32[i] ==
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001021 previewFpsRange[0]) &&
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001022 (availablePreviewFpsRanges.data.i32[i+1] ==
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001023 previewFpsRange[1]) ) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001024 break;
1025 }
1026 }
1027 if (i == availablePreviewFpsRanges.count) {
1028 ALOGE("%s: Requested preview FPS range %d - %d is not supported",
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001029 __FUNCTION__, previewFpsRange[0], previewFpsRange[1]);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001030 return BAD_VALUE;
1031 }
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001032 previewFps = previewFpsRange[0];
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001033 }
1034
1035 // PREVIEW_FORMAT
1036 int previewFormat = formatStringToEnum(newParams.getPreviewFormat());
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001037 if (previewFormat != k.mParameters.previewFormat) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001038 if (mState >= PREVIEW) {
1039 ALOGE("%s: Preview format cannot be updated when preview "
1040 "is active!", __FUNCTION__);
1041 return BAD_VALUE;
1042 }
1043 camera_metadata_entry_t availableFormats =
1044 staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
1045 for (i = 0; i < availableFormats.count; i++) {
1046 if (availableFormats.data.i32[i] == previewFormat) break;
1047 }
1048 if (i == availableFormats.count) {
1049 ALOGE("%s: Requested preview format %s (0x%x) is not supported",
1050 __FUNCTION__, newParams.getPreviewFormat(), previewFormat);
1051 return BAD_VALUE;
1052 }
1053 }
1054
1055 // PREVIEW_FRAME_RATE
1056 // Deprecated, only use if the preview fps range is unchanged this time.
1057 // The single-value FPS is the same as the minimum of the range.
1058 if (!fpsRangeChanged) {
1059 previewFps = newParams.getPreviewFrameRate();
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001060 if (previewFps != k.mParameters.previewFps) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001061 camera_metadata_entry_t availableFrameRates =
1062 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
1063 for (i = 0; i < availableFrameRates.count; i+=2) {
1064 if (availableFrameRates.data.i32[i] == previewFps) break;
1065 }
1066 if (i == availableFrameRates.count) {
1067 ALOGE("%s: Requested preview frame rate %d is not supported",
1068 __FUNCTION__, previewFps);
1069 return BAD_VALUE;
1070 }
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001071 previewFpsRange[0] = availableFrameRates.data.i32[i];
1072 previewFpsRange[1] = availableFrameRates.data.i32[i+1];
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001073 }
1074 }
1075
1076 // PICTURE_SIZE
1077 int pictureWidth, pictureHeight;
1078 newParams.getPictureSize(&pictureWidth, &pictureHeight);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001079 if (pictureWidth == k.mParameters.pictureWidth ||
1080 pictureHeight == k.mParameters.pictureHeight) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001081 camera_metadata_entry_t availablePictureSizes =
1082 staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES);
1083 for (i = 0; i < availablePictureSizes.count; i+=2) {
1084 if (availablePictureSizes.data.i32[i] == pictureWidth &&
1085 availablePictureSizes.data.i32[i+1] == pictureHeight) break;
1086 }
1087 if (i == availablePictureSizes.count) {
1088 ALOGE("%s: Requested picture size %d x %d is not supported",
1089 __FUNCTION__, pictureWidth, pictureHeight);
1090 return BAD_VALUE;
1091 }
1092 }
1093
1094 // JPEG_THUMBNAIL_WIDTH/HEIGHT
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001095 int jpegThumbSize[2];
1096 jpegThumbSize[0] =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001097 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001098 jpegThumbSize[1] =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001099 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001100 if (jpegThumbSize[0] != k.mParameters.jpegThumbSize[0] ||
1101 jpegThumbSize[1] != k.mParameters.jpegThumbSize[1]) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001102 camera_metadata_entry_t availableJpegThumbSizes =
1103 staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES);
1104 for (i = 0; i < availableJpegThumbSizes.count; i+=2) {
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001105 if (availableJpegThumbSizes.data.i32[i] == jpegThumbSize[0] &&
1106 availableJpegThumbSizes.data.i32[i+1] == jpegThumbSize[1]) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001107 break;
1108 }
1109 }
1110 if (i == availableJpegThumbSizes.count) {
1111 ALOGE("%s: Requested JPEG thumbnail size %d x %d is not supported",
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001112 __FUNCTION__, jpegThumbSize[0], jpegThumbSize[1]);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001113 return BAD_VALUE;
1114 }
1115 }
1116
1117 // JPEG_THUMBNAIL_QUALITY
1118 int jpegThumbQuality =
1119 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
1120 if (jpegThumbQuality < 0 || jpegThumbQuality > 100) {
1121 ALOGE("%s: Requested JPEG thumbnail quality %d is not supported",
1122 __FUNCTION__, jpegThumbQuality);
1123 return BAD_VALUE;
1124 }
1125
1126 // JPEG_QUALITY
1127 int jpegQuality =
1128 newParams.getInt(CameraParameters::KEY_JPEG_QUALITY);
1129 if (jpegQuality < 0 || jpegQuality > 100) {
1130 ALOGE("%s: Requested JPEG quality %d is not supported",
1131 __FUNCTION__, jpegQuality);
1132 return BAD_VALUE;
1133 }
1134
1135 // ROTATION
1136 int jpegRotation =
1137 newParams.getInt(CameraParameters::KEY_ROTATION);
1138 if (jpegRotation != 0 &&
1139 jpegRotation != 90 &&
1140 jpegRotation != 180 &&
1141 jpegRotation != 270) {
1142 ALOGE("%s: Requested picture rotation angle %d is not supported",
1143 __FUNCTION__, jpegRotation);
1144 return BAD_VALUE;
1145 }
1146
1147 // GPS
1148 bool gpsEnabled = false;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001149 double gpsCoordinates[3] = {0,0,0};
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001150 int64_t gpsTimestamp = 0;
1151 String8 gpsProcessingMethod;
1152 const char *gpsLatStr =
1153 newParams.get(CameraParameters::KEY_GPS_LATITUDE);
1154 if (gpsLatStr != NULL) {
1155 const char *gpsLongStr =
1156 newParams.get(CameraParameters::KEY_GPS_LONGITUDE);
1157 const char *gpsAltitudeStr =
1158 newParams.get(CameraParameters::KEY_GPS_ALTITUDE);
1159 const char *gpsTimeStr =
1160 newParams.get(CameraParameters::KEY_GPS_TIMESTAMP);
1161 const char *gpsProcMethodStr =
1162 newParams.get(CameraParameters::KEY_GPS_PROCESSING_METHOD);
1163 if (gpsLongStr == NULL ||
1164 gpsAltitudeStr == NULL ||
1165 gpsTimeStr == NULL ||
1166 gpsProcMethodStr == NULL) {
1167 ALOGE("%s: Incomplete set of GPS parameters provided",
1168 __FUNCTION__);
1169 return BAD_VALUE;
1170 }
1171 char *endPtr;
1172 errno = 0;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001173 gpsCoordinates[0] = strtod(gpsLatStr, &endPtr);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001174 if (errno || endPtr == gpsLatStr) {
1175 ALOGE("%s: Malformed GPS latitude: %s", __FUNCTION__, gpsLatStr);
1176 return BAD_VALUE;
1177 }
1178 errno = 0;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001179 gpsCoordinates[1] = strtod(gpsLongStr, &endPtr);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001180 if (errno || endPtr == gpsLongStr) {
1181 ALOGE("%s: Malformed GPS longitude: %s", __FUNCTION__, gpsLongStr);
1182 return BAD_VALUE;
1183 }
1184 errno = 0;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001185 gpsCoordinates[2] = strtod(gpsAltitudeStr, &endPtr);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001186 if (errno || endPtr == gpsAltitudeStr) {
1187 ALOGE("%s: Malformed GPS altitude: %s", __FUNCTION__,
1188 gpsAltitudeStr);
1189 return BAD_VALUE;
1190 }
1191 errno = 0;
1192 gpsTimestamp = strtoll(gpsTimeStr, &endPtr, 10);
1193 if (errno || endPtr == gpsTimeStr) {
1194 ALOGE("%s: Malformed GPS timestamp: %s", __FUNCTION__, gpsTimeStr);
1195 return BAD_VALUE;
1196 }
1197 gpsProcessingMethod = gpsProcMethodStr;
1198
1199 gpsEnabled = true;
1200 }
1201
1202 // WHITE_BALANCE
1203 int wbMode = wbModeStringToEnum(
1204 newParams.get(CameraParameters::KEY_WHITE_BALANCE) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001205 if (wbMode != k.mParameters.wbMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001206 camera_metadata_entry_t availableWbModes =
1207 staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
1208 for (i = 0; i < availableWbModes.count; i++) {
1209 if (wbMode == availableWbModes.data.u8[i]) break;
1210 }
1211 if (i == availableWbModes.count) {
1212 ALOGE("%s: Requested white balance mode %s is not supported",
1213 __FUNCTION__,
1214 newParams.get(CameraParameters::KEY_WHITE_BALANCE));
1215 return BAD_VALUE;
1216 }
1217 }
1218
1219 // EFFECT
1220 int effectMode = effectModeStringToEnum(
1221 newParams.get(CameraParameters::KEY_EFFECT) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001222 if (effectMode != k.mParameters.effectMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001223 camera_metadata_entry_t availableEffectModes =
1224 staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
1225 for (i = 0; i < availableEffectModes.count; i++) {
1226 if (effectMode == availableEffectModes.data.u8[i]) break;
1227 }
1228 if (i == availableEffectModes.count) {
1229 ALOGE("%s: Requested effect mode \"%s\" is not supported",
1230 __FUNCTION__,
1231 newParams.get(CameraParameters::KEY_EFFECT) );
1232 return BAD_VALUE;
1233 }
1234 }
1235
1236 // ANTIBANDING
1237 int antibandingMode = abModeStringToEnum(
1238 newParams.get(CameraParameters::KEY_ANTIBANDING) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001239 if (antibandingMode != k.mParameters.antibandingMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001240 camera_metadata_entry_t availableAbModes =
1241 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
1242 for (i = 0; i < availableAbModes.count; i++) {
1243 if (antibandingMode == availableAbModes.data.u8[i]) break;
1244 }
1245 if (i == availableAbModes.count) {
1246 ALOGE("%s: Requested antibanding mode \"%s\" is not supported",
1247 __FUNCTION__,
1248 newParams.get(CameraParameters::KEY_ANTIBANDING));
1249 return BAD_VALUE;
1250 }
1251 }
1252
1253 // SCENE_MODE
1254 int sceneMode = sceneModeStringToEnum(
1255 newParams.get(CameraParameters::KEY_SCENE_MODE) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001256 if (sceneMode != k.mParameters.sceneMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001257 camera_metadata_entry_t availableSceneModes =
1258 staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
1259 for (i = 0; i < availableSceneModes.count; i++) {
1260 if (sceneMode == availableSceneModes.data.u8[i]) break;
1261 }
1262 if (i == availableSceneModes.count) {
1263 ALOGE("%s: Requested scene mode \"%s\" is not supported",
1264 __FUNCTION__,
1265 newParams.get(CameraParameters::KEY_SCENE_MODE));
1266 return BAD_VALUE;
1267 }
1268 }
1269
1270 // FLASH_MODE
1271 Parameters::flashMode_t flashMode = flashModeStringToEnum(
1272 newParams.get(CameraParameters::KEY_FLASH_MODE) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001273 if (flashMode != k.mParameters.flashMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001274 camera_metadata_entry_t flashAvailable =
1275 staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
1276 if (!flashAvailable.data.u8[0] &&
1277 flashMode != Parameters::FLASH_MODE_OFF) {
1278 ALOGE("%s: Requested flash mode \"%s\" is not supported: "
1279 "No flash on device", __FUNCTION__,
1280 newParams.get(CameraParameters::KEY_FLASH_MODE));
1281 return BAD_VALUE;
1282 } else if (flashMode == Parameters::FLASH_MODE_RED_EYE) {
1283 camera_metadata_entry_t availableAeModes =
1284 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
1285 for (i = 0; i < availableAeModes.count; i++) {
1286 if (flashMode == availableAeModes.data.u8[i]) break;
1287 }
1288 if (i == availableAeModes.count) {
1289 ALOGE("%s: Requested flash mode \"%s\" is not supported",
1290 __FUNCTION__,
1291 newParams.get(CameraParameters::KEY_FLASH_MODE));
1292 return BAD_VALUE;
1293 }
1294 } else if (flashMode == -1) {
1295 ALOGE("%s: Requested flash mode \"%s\" is unknown",
1296 __FUNCTION__,
1297 newParams.get(CameraParameters::KEY_FLASH_MODE));
1298 return BAD_VALUE;
1299 }
1300 }
1301
1302 // FOCUS_MODE
1303 Parameters::focusMode_t focusMode = focusModeStringToEnum(
1304 newParams.get(CameraParameters::KEY_FOCUS_MODE));
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001305 if (focusMode != k.mParameters.focusMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001306 if (focusMode != Parameters::FOCUS_MODE_FIXED) {
1307 camera_metadata_entry_t minFocusDistance =
1308 staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE);
1309 if (minFocusDistance.data.f[0] == 0) {
1310 ALOGE("%s: Requested focus mode \"%s\" is not available: "
1311 "fixed focus lens",
1312 __FUNCTION__,
1313 newParams.get(CameraParameters::KEY_FOCUS_MODE));
1314 return BAD_VALUE;
1315 } else if (focusMode != Parameters::FOCUS_MODE_INFINITY) {
1316 camera_metadata_entry_t availableFocusModes =
1317 staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
1318 for (i = 0; i < availableFocusModes.count; i++) {
1319 if (focusMode == availableFocusModes.data.u8[i]) break;
1320 }
1321 if (i == availableFocusModes.count) {
1322 ALOGE("%s: Requested focus mode \"%s\" is not supported",
1323 __FUNCTION__,
1324 newParams.get(CameraParameters::KEY_FOCUS_MODE));
1325 return BAD_VALUE;
1326 }
1327 }
1328 }
1329 }
1330
1331 // FOCUS_AREAS
1332 Vector<Parameters::Area> focusingAreas;
1333 res = parseAreas(newParams.get(CameraParameters::KEY_FOCUS_AREAS),
1334 &focusingAreas);
1335 size_t max3aRegions =
1336 (size_t)staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1).data.i32[0];
1337 if (res == OK) res = validateAreas(focusingAreas, max3aRegions);
1338 if (res != OK) {
1339 ALOGE("%s: Requested focus areas are malformed: %s",
1340 __FUNCTION__, newParams.get(CameraParameters::KEY_FOCUS_AREAS));
1341 return BAD_VALUE;
1342 }
1343
1344 // EXPOSURE_COMPENSATION
1345 int exposureCompensation =
1346 newParams.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION);
1347 camera_metadata_entry_t exposureCompensationRange =
1348 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE);
1349 if (exposureCompensation < exposureCompensationRange.data.i32[0] ||
1350 exposureCompensation > exposureCompensationRange.data.i32[1]) {
1351 ALOGE("%s: Requested exposure compensation index is out of bounds: %d",
1352 __FUNCTION__, exposureCompensation);
1353 return BAD_VALUE;
1354 }
1355
1356 // AUTO_EXPOSURE_LOCK (always supported)
1357 bool autoExposureLock = boolFromString(
1358 newParams.get(CameraParameters::KEY_AUTO_EXPOSURE_LOCK));
1359
1360 // AUTO_WHITEBALANCE_LOCK (always supported)
1361 bool autoWhiteBalanceLock = boolFromString(
1362 newParams.get(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK));
1363
1364 // METERING_AREAS
1365 Vector<Parameters::Area> meteringAreas;
1366 res = parseAreas(newParams.get(CameraParameters::KEY_METERING_AREAS),
1367 &meteringAreas);
1368 if (res == OK) res = validateAreas(focusingAreas, max3aRegions);
1369 if (res != OK) {
1370 ALOGE("%s: Requested metering areas are malformed: %s",
1371 __FUNCTION__,
1372 newParams.get(CameraParameters::KEY_METERING_AREAS));
1373 return BAD_VALUE;
1374 }
1375
1376 // ZOOM
1377 int zoom = newParams.getInt(CameraParameters::KEY_ZOOM);
1378 if (zoom < 0 || zoom > (int)NUM_ZOOM_STEPS) {
1379 ALOGE("%s: Requested zoom level %d is not supported",
1380 __FUNCTION__, zoom);
1381 return BAD_VALUE;
1382 }
1383
1384 // VIDEO_SIZE
1385 int videoWidth, videoHeight;
1386 newParams.getVideoSize(&videoWidth, &videoHeight);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001387 if (videoWidth != k.mParameters.videoWidth ||
1388 videoHeight != k.mParameters.videoHeight) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001389 if (mState == RECORD) {
1390 ALOGE("%s: Video size cannot be updated when recording is active!",
1391 __FUNCTION__);
1392 return BAD_VALUE;
1393 }
1394 camera_metadata_entry_t availableVideoSizes =
1395 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
1396 for (i = 0; i < availableVideoSizes.count; i += 2 ) {
1397 if (availableVideoSizes.data.i32[i] == videoWidth &&
1398 availableVideoSizes.data.i32[i+1] == videoHeight) break;
1399 }
1400 if (i == availableVideoSizes.count) {
1401 ALOGE("%s: Requested video size %d x %d is not supported",
1402 __FUNCTION__, videoWidth, videoHeight);
1403 return BAD_VALUE;
1404 }
1405 }
1406
1407 // RECORDING_HINT (always supported)
1408 bool recordingHint = boolFromString(
1409 newParams.get(CameraParameters::KEY_RECORDING_HINT) );
1410
1411 // VIDEO_STABILIZATION
1412 bool videoStabilization = boolFromString(
1413 newParams.get(CameraParameters::KEY_VIDEO_STABILIZATION) );
1414 camera_metadata_entry_t availableVideoStabilizationModes =
1415 staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
1416 if (videoStabilization && availableVideoStabilizationModes.count == 1) {
1417 ALOGE("%s: Video stabilization not supported", __FUNCTION__);
1418 }
1419
1420 /** Update internal parameters */
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001421
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001422 k.mParameters.previewWidth = previewWidth;
1423 k.mParameters.previewHeight = previewHeight;
1424 k.mParameters.previewFpsRange[0] = previewFpsRange[0];
1425 k.mParameters.previewFpsRange[1] = previewFpsRange[1];
1426 k.mParameters.previewFps = previewFps;
1427 k.mParameters.previewFormat = previewFormat;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001428
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001429 k.mParameters.pictureWidth = pictureWidth;
1430 k.mParameters.pictureHeight = pictureHeight;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001431
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001432 k.mParameters.jpegThumbSize[0] = jpegThumbSize[0];
1433 k.mParameters.jpegThumbSize[1] = jpegThumbSize[1];
1434 k.mParameters.jpegQuality = jpegQuality;
1435 k.mParameters.jpegThumbQuality = jpegThumbQuality;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001436
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001437 k.mParameters.gpsEnabled = gpsEnabled;
1438 k.mParameters.gpsCoordinates[0] = gpsCoordinates[0];
1439 k.mParameters.gpsCoordinates[1] = gpsCoordinates[1];
1440 k.mParameters.gpsCoordinates[2] = gpsCoordinates[2];
1441 k.mParameters.gpsTimestamp = gpsTimestamp;
1442 k.mParameters.gpsProcessingMethod = gpsProcessingMethod;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001443
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001444 k.mParameters.wbMode = wbMode;
1445 k.mParameters.effectMode = effectMode;
1446 k.mParameters.antibandingMode = antibandingMode;
1447 k.mParameters.sceneMode = sceneMode;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001448
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001449 k.mParameters.flashMode = flashMode;
1450 k.mParameters.focusMode = focusMode;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001451
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001452 k.mParameters.focusingAreas = focusingAreas;
1453 k.mParameters.exposureCompensation = exposureCompensation;
1454 k.mParameters.autoExposureLock = autoExposureLock;
1455 k.mParameters.autoWhiteBalanceLock = autoWhiteBalanceLock;
1456 k.mParameters.meteringAreas = meteringAreas;
1457 k.mParameters.zoom = zoom;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001458
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001459 k.mParameters.videoWidth = videoWidth;
1460 k.mParameters.videoHeight = videoHeight;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001461
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001462 k.mParameters.recordingHint = recordingHint;
1463 k.mParameters.videoStabilization = videoStabilization;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001464
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001465 res = updatePreviewRequest(k.mParameters);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001466 if (res != OK) {
1467 ALOGE("%s: Camera %d: Unable to update preview request: %s (%d)",
1468 __FUNCTION__, mCameraId, strerror(-res), res);
1469 return res;
1470 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001471 res = updateCaptureRequest(k.mParameters);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001472 if (res != OK) {
1473 ALOGE("%s: Camera %d: Unable to update capture request: %s (%d)",
1474 __FUNCTION__, mCameraId, strerror(-res), res);
1475 return res;
1476 }
1477
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001478 res = updateRecordingRequest(k.mParameters);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001479 if (res != OK) {
1480 ALOGE("%s: Camera %d: Unable to update recording request: %s (%d)",
1481 __FUNCTION__, mCameraId, strerror(-res), res);
1482 return res;
1483 }
1484
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001485 if (mState == PREVIEW) {
1486 res = mDevice->setStreamingRequest(mPreviewRequest);
1487 if (res != OK) {
1488 ALOGE("%s: Camera %d: Error streaming new preview request: %s (%d)",
1489 __FUNCTION__, mCameraId, strerror(-res), res);
1490 return res;
1491 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001492 } else if (mState == RECORD || mState == VIDEO_SNAPSHOT) {
1493 res = mDevice->setStreamingRequest(mRecordingRequest);
1494 if (res != OK) {
1495 ALOGE("%s: Camera %d: Error streaming new record request: %s (%d)",
1496 __FUNCTION__, mCameraId, strerror(-res), res);
1497 return res;
1498 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001499 }
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001500
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001501 k.mParameters.paramsFlattened = params;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001502
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001503 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001504}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001505
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001506String8 Camera2Client::getParameters() const {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001507 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001508 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001509 if ( checkPid(__FUNCTION__) != OK) return String8();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001510
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001511 LockedParameters::ReadKey k(mParameters);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001512
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001513 // TODO: Deal with focus distances
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001514 return k.mParameters.paramsFlattened;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001515}
1516
1517status_t Camera2Client::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001518 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001519 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001520 status_t res;
1521 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001522
1523 ALOGV("%s: Camera %d: Command %d (%d, %d)", __FUNCTION__, mCameraId,
1524 cmd, arg1, arg2);
1525
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001526 switch (cmd) {
1527 case CAMERA_CMD_START_SMOOTH_ZOOM:
1528 return commandStartSmoothZoomL();
1529 case CAMERA_CMD_STOP_SMOOTH_ZOOM:
1530 return commandStopSmoothZoomL();
1531 case CAMERA_CMD_SET_DISPLAY_ORIENTATION:
1532 return commandSetDisplayOrientationL(arg1);
1533 case CAMERA_CMD_ENABLE_SHUTTER_SOUND:
1534 return commandEnableShutterSoundL(arg1 == 1);
1535 case CAMERA_CMD_PLAY_RECORDING_SOUND:
1536 return commandPlayRecordingSoundL();
1537 case CAMERA_CMD_START_FACE_DETECTION:
1538 return commandStartFaceDetectionL(arg1);
1539 case CAMERA_CMD_STOP_FACE_DETECTION:
1540 return commandStopFaceDetectionL();
1541 case CAMERA_CMD_ENABLE_FOCUS_MOVE_MSG:
1542 return commandEnableFocusMoveMsgL(arg1 == 1);
1543 case CAMERA_CMD_PING:
1544 return commandPingL();
1545 case CAMERA_CMD_SET_VIDEO_BUFFER_COUNT:
1546 return commandSetVideoBufferCountL(arg1);
1547 default:
1548 ALOGE("%s: Unknown command %d (arguments %d, %d)",
1549 __FUNCTION__, cmd, arg1, arg2);
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001550 return BAD_VALUE;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001551 }
1552}
James Dong983cf232012-08-01 16:39:55 -07001553
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001554status_t Camera2Client::commandStartSmoothZoomL() {
1555 ALOGE("%s: Unimplemented!", __FUNCTION__);
1556 return OK;
1557}
James Dong983cf232012-08-01 16:39:55 -07001558
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001559status_t Camera2Client::commandStopSmoothZoomL() {
1560 ALOGE("%s: Unimplemented!", __FUNCTION__);
1561 return OK;
1562}
James Dong983cf232012-08-01 16:39:55 -07001563
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001564status_t Camera2Client::commandSetDisplayOrientationL(int degrees) {
1565 LockedParameters::Key k(mParameters);
1566 int transform = degToTransform(degrees,
1567 mCameraFacing == CAMERA_FACING_FRONT);
1568 if (transform == -1) {
1569 ALOGE("%s: Camera %d: Error setting %d as display orientation value",
1570 __FUNCTION__, mCameraId, degrees);
1571 return BAD_VALUE;
1572 }
1573 if (transform != k.mParameters.previewTransform &&
1574 mPreviewStreamId != NO_STREAM) {
1575 mDevice->setStreamTransform(mPreviewStreamId, transform);
1576 }
1577 k.mParameters.previewTransform = transform;
1578 return OK;
1579}
1580
1581status_t Camera2Client::commandEnableShutterSoundL(bool enable) {
1582 LockedParameters::Key k(mParameters);
1583 if (enable) {
1584 k.mParameters.playShutterSound = true;
James Dong983cf232012-08-01 16:39:55 -07001585 return OK;
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001586 }
1587
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001588 // Disabling shutter sound may not be allowed. In that case only
1589 // allow the mediaserver process to disable the sound.
1590 char value[PROPERTY_VALUE_MAX];
1591 property_get("ro.camera.sound.forced", value, "0");
1592 if (strncmp(value, "0", 2) != 0) {
1593 // Disabling shutter sound is not allowed. Deny if the current
1594 // process is not mediaserver.
1595 if (getCallingPid() != getpid()) {
1596 ALOGE("Failed to disable shutter sound. Permission denied (pid %d)",
1597 getCallingPid());
1598 return PERMISSION_DENIED;
1599 }
1600 }
1601
1602 k.mParameters.playShutterSound = false;
1603 return OK;
1604}
1605
1606status_t Camera2Client::commandPlayRecordingSoundL() {
1607 mCameraService->playSound(CameraService::SOUND_RECORDING);
1608 return OK;
1609}
1610
1611status_t Camera2Client::commandStartFaceDetectionL(int type) {
1612 ALOGE("%s: Unimplemented!", __FUNCTION__);
1613 return OK;
1614}
1615
1616status_t Camera2Client::commandStopFaceDetectionL() {
1617 ALOGE("%s: Unimplemented!", __FUNCTION__);
1618 return OK;
1619}
1620
1621status_t Camera2Client::commandEnableFocusMoveMsgL(bool enable) {
1622 ALOGE("%s: Unimplemented!", __FUNCTION__);
1623 return OK;
1624}
1625
1626status_t Camera2Client::commandPingL() {
1627 // Always ping back if access is proper and device is alive
1628 if (mState != DISCONNECTED) {
1629 return OK;
1630 } else {
1631 return NO_INIT;
1632 }
1633}
1634
1635status_t Camera2Client::commandSetVideoBufferCountL(size_t count) {
1636 if (recordingEnabled()) {
1637 ALOGE("%s: Camera %d: Error setting video buffer count after "
1638 "recording was started", __FUNCTION__, mCameraId);
1639 return INVALID_OPERATION;
1640 }
1641
1642 // 32 is the current upper limit on the video buffer count for BufferQueue
1643 if (count > 32) {
1644 ALOGE("%s: Camera %d: Error setting %d as video buffer count value",
1645 __FUNCTION__, mCameraId, count);
1646 return BAD_VALUE;
1647 }
1648
1649 // Need to reallocate memory for heap
1650 if (mRecordingHeapCount != count) {
1651 if (mRecordingHeap != 0) {
1652 mRecordingHeap.clear();
1653 mRecordingHeap = NULL;
1654 }
1655 mRecordingHeapCount = count;
1656 }
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001657
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001658 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001659}
1660
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001661/** Device-related methods */
1662
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001663void Camera2Client::onCaptureAvailable() {
1664 ATRACE_CALL();
1665 status_t res;
1666 sp<ICameraClient> currentClient;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001667 ALOGV("%s: Camera %d: Still capture available", __FUNCTION__, mCameraId);
1668
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001669 CpuConsumer::LockedBuffer imgBuffer;
1670 {
1671 Mutex::Autolock icl(mICameraLock);
1672
1673 // TODO: Signal errors here upstream
1674 if (mState != STILL_CAPTURE && mState != VIDEO_SNAPSHOT) {
1675 ALOGE("%s: Camera %d: Still image produced unexpectedly!",
1676 __FUNCTION__, mCameraId);
1677 return;
1678 }
1679
1680 res = mCaptureConsumer->lockNextBuffer(&imgBuffer);
1681 if (res != OK) {
1682 ALOGE("%s: Camera %d: Error receiving still image buffer: %s (%d)",
1683 __FUNCTION__, mCameraId, strerror(-res), res);
1684 return;
1685 }
1686
1687 if (imgBuffer.format != HAL_PIXEL_FORMAT_BLOB) {
1688 ALOGE("%s: Camera %d: Unexpected format for still image: "
1689 "%x, expected %x", __FUNCTION__, mCameraId,
1690 imgBuffer.format,
1691 HAL_PIXEL_FORMAT_BLOB);
1692 mCaptureConsumer->unlockBuffer(imgBuffer);
1693 return;
1694 }
1695
1696 // TODO: Optimize this to avoid memcopy
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001697 void* captureMemory = mCaptureHeap->mHeap->getBase();
1698 size_t size = mCaptureHeap->mHeap->getSize();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001699 memcpy(captureMemory, imgBuffer.data, size);
1700
1701 mCaptureConsumer->unlockBuffer(imgBuffer);
1702
1703 currentClient = mCameraClient;
1704 switch (mState) {
1705 case STILL_CAPTURE:
1706 mState = STOPPED;
1707 break;
1708 case VIDEO_SNAPSHOT:
1709 mState = RECORD;
1710 break;
1711 default:
1712 ALOGE("%s: Camera %d: Unexpected state %d", __FUNCTION__,
1713 mCameraId, mState);
1714 break;
1715 }
1716 }
1717 // Call outside mICameraLock to allow re-entrancy from notification
1718 if (currentClient != 0) {
1719 currentClient->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001720 mCaptureHeap->mBuffers[0], NULL);
1721 }
1722}
1723
1724void Camera2Client::onRecordingFrameAvailable() {
1725 ATRACE_CALL();
1726 status_t res;
1727 sp<ICameraClient> currentClient;
1728 size_t heapIdx = 0;
1729 nsecs_t timestamp;
1730 {
1731 Mutex::Autolock icl(mICameraLock);
1732 // TODO: Signal errors here upstream
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001733 bool discardData = false;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001734 if (mState != RECORD && mState != VIDEO_SNAPSHOT) {
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001735 ALOGV("%s: Camera %d: Discarding recording image buffers received after "
1736 "recording done",
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001737 __FUNCTION__, mCameraId);
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001738 discardData = true;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001739 }
1740
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001741 buffer_handle_t imgBuffer;
1742 res = mRecordingConsumer->getNextBuffer(&imgBuffer, &timestamp);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001743 if (res != OK) {
1744 ALOGE("%s: Camera %d: Error receiving recording buffer: %s (%d)",
1745 __FUNCTION__, mCameraId, strerror(-res), res);
1746 return;
1747 }
1748
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001749 if (discardData) {
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001750 mRecordingConsumer->freeBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001751 return;
1752 }
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001753
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001754 if (mRecordingHeap == 0) {
1755 const size_t bufferSize = 4 + sizeof(buffer_handle_t);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001756 ALOGV("%s: Camera %d: Creating recording heap with %d buffers of "
1757 "size %d bytes", __FUNCTION__, mCameraId,
James Dong983cf232012-08-01 16:39:55 -07001758 mRecordingHeapCount, bufferSize);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001759 if (mRecordingHeap != 0) {
1760 ALOGV("%s: Camera %d: Previous heap has size %d "
1761 "(new will be %d) bytes", __FUNCTION__, mCameraId,
1762 mRecordingHeap->mHeap->getSize(),
James Dong983cf232012-08-01 16:39:55 -07001763 bufferSize * mRecordingHeapCount);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001764 }
1765 // Need to allocate memory for heap
1766 mRecordingHeap.clear();
1767
James Dong983cf232012-08-01 16:39:55 -07001768 mRecordingHeap = new Camera2Heap(bufferSize, mRecordingHeapCount,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001769 "Camera2Client::RecordingHeap");
1770 if (mRecordingHeap->mHeap->getSize() == 0) {
1771 ALOGE("%s: Camera %d: Unable to allocate memory for recording",
1772 __FUNCTION__, mCameraId);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001773 mRecordingConsumer->freeBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001774 return;
1775 }
1776 mRecordingHeapHead = 0;
James Dong983cf232012-08-01 16:39:55 -07001777 mRecordingHeapFree = mRecordingHeapCount;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001778 }
1779
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001780 if ( mRecordingHeapFree == 0) {
1781 ALOGE("%s: Camera %d: No free recording buffers, dropping frame",
1782 __FUNCTION__, mCameraId);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001783 mRecordingConsumer->freeBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001784 return;
1785 }
1786 heapIdx = mRecordingHeapHead;
James Dong983cf232012-08-01 16:39:55 -07001787 mRecordingHeapHead = (mRecordingHeapHead + 1) % mRecordingHeapCount;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001788 mRecordingHeapFree--;
1789
1790 ALOGV("%s: Camera %d: Timestamp %lld",
1791 __FUNCTION__, mCameraId, timestamp);
1792
1793 ssize_t offset;
1794 size_t size;
1795 sp<IMemoryHeap> heap =
1796 mRecordingHeap->mBuffers[heapIdx]->getMemory(&offset,
1797 &size);
1798
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001799 uint8_t *data = (uint8_t*)heap->getBase() + offset;
1800 uint32_t type = kMetadataBufferTypeGrallocSource;
1801 memcpy(data, &type, 4);
1802 memcpy(data + 4, &imgBuffer, sizeof(buffer_handle_t));
1803 ALOGV("%s: Camera %d: Sending out buffer_handle_t %p",
Eino-Ville Talvala803cbf62012-07-25 15:23:36 -07001804 __FUNCTION__, mCameraId, imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001805 currentClient = mCameraClient;
1806 }
1807 // Call outside mICameraLock to allow re-entrancy from notification
1808 if (currentClient != 0) {
1809 currentClient->dataCallbackTimestamp(timestamp,
1810 CAMERA_MSG_VIDEO_FRAME,
1811 mRecordingHeap->mBuffers[heapIdx]);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001812 }
1813}
1814
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001815camera_metadata_entry_t Camera2Client::staticInfo(uint32_t tag,
1816 size_t minCount, size_t maxCount) {
1817 status_t res;
1818 camera_metadata_entry_t entry;
1819 res = find_camera_metadata_entry(mDevice->info(),
1820 tag,
1821 &entry);
1822 if (CC_UNLIKELY( res != OK )) {
1823 const char* tagSection = get_camera_metadata_section_name(tag);
1824 if (tagSection == NULL) tagSection = "<unknown>";
1825 const char* tagName = get_camera_metadata_tag_name(tag);
1826 if (tagName == NULL) tagName = "<unknown>";
1827
1828 ALOGE("Error finding static metadata entry '%s.%s' (%x): %s (%d)",
1829 tagSection, tagName, tag, strerror(-res), res);
1830 entry.count = 0;
1831 entry.data.u8 = NULL;
1832 } else if (CC_UNLIKELY(
1833 (minCount != 0 && entry.count < minCount) ||
1834 (maxCount != 0 && entry.count > maxCount) ) ) {
1835 const char* tagSection = get_camera_metadata_section_name(tag);
1836 if (tagSection == NULL) tagSection = "<unknown>";
1837 const char* tagName = get_camera_metadata_tag_name(tag);
1838 if (tagName == NULL) tagName = "<unknown>";
1839 ALOGE("Malformed static metadata entry '%s.%s' (%x):"
1840 "Expected between %d and %d values, but got %d values",
1841 tagSection, tagName, tag, minCount, maxCount, entry.count);
1842 entry.count = 0;
1843 entry.data.u8 = NULL;
1844 }
1845
1846 return entry;
1847}
1848
1849/** Utility methods */
1850
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001851
1852status_t Camera2Client::buildDefaultParameters() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001853 ATRACE_CALL();
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001854 LockedParameters::Key k(mParameters);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001855
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001856 status_t res;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001857 CameraParameters params;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001858
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001859 camera_metadata_entry_t availableProcessedSizes =
1860 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES, 2);
1861 if (!availableProcessedSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001862
1863 // TODO: Pick more intelligently
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001864 k.mParameters.previewWidth = availableProcessedSizes.data.i32[0];
1865 k.mParameters.previewHeight = availableProcessedSizes.data.i32[1];
1866 k.mParameters.videoWidth = k.mParameters.previewWidth;
1867 k.mParameters.videoHeight = k.mParameters.previewHeight;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001868
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001869 params.setPreviewSize(k.mParameters.previewWidth, k.mParameters.previewHeight);
1870 params.setVideoSize(k.mParameters.videoWidth, k.mParameters.videoHeight);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001871 params.set(CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO,
1872 String8::format("%dx%d",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001873 k.mParameters.previewWidth, k.mParameters.previewHeight));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001874 {
1875 String8 supportedPreviewSizes;
1876 for (size_t i=0; i < availableProcessedSizes.count; i += 2) {
1877 if (i != 0) supportedPreviewSizes += ",";
1878 supportedPreviewSizes += String8::format("%dx%d",
1879 availableProcessedSizes.data.i32[i],
1880 availableProcessedSizes.data.i32[i+1]);
1881 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001882 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001883 supportedPreviewSizes);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001884 params.set(CameraParameters::KEY_SUPPORTED_VIDEO_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001885 supportedPreviewSizes);
1886 }
1887
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001888 camera_metadata_entry_t availableFpsRanges =
1889 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
1890 if (!availableFpsRanges.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001891
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001892 k.mParameters.previewFpsRange[0] = availableFpsRanges.data.i32[0];
1893 k.mParameters.previewFpsRange[1] = availableFpsRanges.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001894
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001895 params.set(CameraParameters::KEY_PREVIEW_FPS_RANGE,
1896 String8::format("%d,%d",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001897 k.mParameters.previewFpsRange[0],
1898 k.mParameters.previewFpsRange[1]));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001899
1900 {
1901 String8 supportedPreviewFpsRange;
1902 for (size_t i=0; i < availableFpsRanges.count; i += 2) {
1903 if (i != 0) supportedPreviewFpsRange += ",";
1904 supportedPreviewFpsRange += String8::format("(%d,%d)",
1905 availableFpsRanges.data.i32[i],
1906 availableFpsRanges.data.i32[i+1]);
1907 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001908 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001909 supportedPreviewFpsRange);
1910 }
1911
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001912 k.mParameters.previewFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001913 params.set(CameraParameters::KEY_PREVIEW_FORMAT,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001914 formatEnumToString(k.mParameters.previewFormat)); // NV21
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001915
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001916 k.mParameters.previewTransform = degToTransform(0,
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001917 mCameraFacing == CAMERA_FACING_FRONT);
1918
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001919 camera_metadata_entry_t availableFormats =
1920 staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
1921
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001922 {
1923 String8 supportedPreviewFormats;
1924 bool addComma = false;
1925 for (size_t i=0; i < availableFormats.count; i++) {
1926 if (addComma) supportedPreviewFormats += ",";
1927 addComma = true;
1928 switch (availableFormats.data.i32[i]) {
1929 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001930 supportedPreviewFormats +=
1931 CameraParameters::PIXEL_FORMAT_YUV422SP;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001932 break;
1933 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001934 supportedPreviewFormats +=
1935 CameraParameters::PIXEL_FORMAT_YUV420SP;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001936 break;
1937 case HAL_PIXEL_FORMAT_YCbCr_422_I:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001938 supportedPreviewFormats +=
1939 CameraParameters::PIXEL_FORMAT_YUV422I;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001940 break;
1941 case HAL_PIXEL_FORMAT_YV12:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001942 supportedPreviewFormats +=
1943 CameraParameters::PIXEL_FORMAT_YUV420P;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001944 break;
1945 case HAL_PIXEL_FORMAT_RGB_565:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001946 supportedPreviewFormats +=
1947 CameraParameters::PIXEL_FORMAT_RGB565;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001948 break;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001949 case HAL_PIXEL_FORMAT_RGBA_8888:
1950 supportedPreviewFormats +=
1951 CameraParameters::PIXEL_FORMAT_RGBA8888;
1952 break;
1953 // Not advertizing JPEG, RAW_SENSOR, etc, for preview formats
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001954 case HAL_PIXEL_FORMAT_RAW_SENSOR:
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001955 case HAL_PIXEL_FORMAT_BLOB:
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001956 addComma = false;
1957 break;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001958
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001959 default:
1960 ALOGW("%s: Camera %d: Unknown preview format: %x",
1961 __FUNCTION__, mCameraId, availableFormats.data.i32[i]);
1962 addComma = false;
1963 break;
1964 }
1965 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001966 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001967 supportedPreviewFormats);
1968 }
1969
1970 // PREVIEW_FRAME_RATE / SUPPORTED_PREVIEW_FRAME_RATES are deprecated, but
1971 // still have to do something sane for them
1972
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001973 params.set(CameraParameters::KEY_PREVIEW_FRAME_RATE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001974 k.mParameters.previewFpsRange[0]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001975
1976 {
1977 String8 supportedPreviewFrameRates;
1978 for (size_t i=0; i < availableFpsRanges.count; i += 2) {
1979 if (i != 0) supportedPreviewFrameRates += ",";
1980 supportedPreviewFrameRates += String8::format("%d",
1981 availableFpsRanges.data.i32[i]);
1982 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001983 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001984 supportedPreviewFrameRates);
1985 }
1986
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001987 camera_metadata_entry_t availableJpegSizes =
1988 staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES, 2);
1989 if (!availableJpegSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001990
1991 // TODO: Pick maximum
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001992 k.mParameters.pictureWidth = availableJpegSizes.data.i32[0];
1993 k.mParameters.pictureHeight = availableJpegSizes.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001994
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001995 params.setPictureSize(k.mParameters.pictureWidth,
1996 k.mParameters.pictureHeight);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001997
1998 {
1999 String8 supportedPictureSizes;
2000 for (size_t i=0; i < availableJpegSizes.count; i += 2) {
2001 if (i != 0) supportedPictureSizes += ",";
2002 supportedPictureSizes += String8::format("%dx%d",
2003 availableJpegSizes.data.i32[i],
2004 availableJpegSizes.data.i32[i+1]);
2005 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002006 params.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002007 supportedPictureSizes);
2008 }
2009
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002010 params.setPictureFormat(CameraParameters::PIXEL_FORMAT_JPEG);
2011 params.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS,
2012 CameraParameters::PIXEL_FORMAT_JPEG);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002013
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002014 camera_metadata_entry_t availableJpegThumbnailSizes =
2015 staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES, 2);
2016 if (!availableJpegThumbnailSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002017
2018 // TODO: Pick default thumbnail size sensibly
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002019 k.mParameters.jpegThumbSize[0] = availableJpegThumbnailSizes.data.i32[0];
2020 k.mParameters.jpegThumbSize[1] = availableJpegThumbnailSizes.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002021
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002022 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002023 k.mParameters.jpegThumbSize[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002024 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002025 k.mParameters.jpegThumbSize[1]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002026
2027 {
2028 String8 supportedJpegThumbSizes;
2029 for (size_t i=0; i < availableJpegThumbnailSizes.count; i += 2) {
2030 if (i != 0) supportedJpegThumbSizes += ",";
2031 supportedJpegThumbSizes += String8::format("%dx%d",
2032 availableJpegThumbnailSizes.data.i32[i],
2033 availableJpegThumbnailSizes.data.i32[i+1]);
2034 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002035 params.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002036 supportedJpegThumbSizes);
2037 }
2038
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002039 k.mParameters.jpegThumbQuality = 90;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002040 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002041 k.mParameters.jpegThumbQuality);
2042 k.mParameters.jpegQuality = 90;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002043 params.set(CameraParameters::KEY_JPEG_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002044 k.mParameters.jpegQuality);
2045 k.mParameters.jpegRotation = 0;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002046 params.set(CameraParameters::KEY_ROTATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002047 k.mParameters.jpegRotation);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002048
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002049 k.mParameters.gpsEnabled = false;
2050 k.mParameters.gpsProcessingMethod = "unknown";
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002051 // GPS fields in CameraParameters are not set by implementation
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002052
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002053 k.mParameters.wbMode = ANDROID_CONTROL_AWB_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002054 params.set(CameraParameters::KEY_WHITE_BALANCE,
2055 CameraParameters::WHITE_BALANCE_AUTO);
2056
2057 camera_metadata_entry_t availableWhiteBalanceModes =
2058 staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002059 {
2060 String8 supportedWhiteBalance;
2061 bool addComma = false;
2062 for (size_t i=0; i < availableWhiteBalanceModes.count; i++) {
2063 if (addComma) supportedWhiteBalance += ",";
2064 addComma = true;
2065 switch (availableWhiteBalanceModes.data.u8[i]) {
2066 case ANDROID_CONTROL_AWB_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002067 supportedWhiteBalance +=
2068 CameraParameters::WHITE_BALANCE_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002069 break;
2070 case ANDROID_CONTROL_AWB_INCANDESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002071 supportedWhiteBalance +=
2072 CameraParameters::WHITE_BALANCE_INCANDESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002073 break;
2074 case ANDROID_CONTROL_AWB_FLUORESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002075 supportedWhiteBalance +=
2076 CameraParameters::WHITE_BALANCE_FLUORESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002077 break;
2078 case ANDROID_CONTROL_AWB_WARM_FLUORESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002079 supportedWhiteBalance +=
2080 CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002081 break;
2082 case ANDROID_CONTROL_AWB_DAYLIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002083 supportedWhiteBalance +=
2084 CameraParameters::WHITE_BALANCE_DAYLIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002085 break;
2086 case ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002087 supportedWhiteBalance +=
2088 CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002089 break;
2090 case ANDROID_CONTROL_AWB_TWILIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002091 supportedWhiteBalance +=
2092 CameraParameters::WHITE_BALANCE_TWILIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002093 break;
2094 case ANDROID_CONTROL_AWB_SHADE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002095 supportedWhiteBalance +=
2096 CameraParameters::WHITE_BALANCE_SHADE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002097 break;
2098 // Skipping values not mappable to v1 API
2099 case ANDROID_CONTROL_AWB_OFF:
2100 addComma = false;
2101 break;
2102 default:
2103 ALOGW("%s: Camera %d: Unknown white balance value: %d",
2104 __FUNCTION__, mCameraId,
2105 availableWhiteBalanceModes.data.u8[i]);
2106 addComma = false;
2107 break;
2108 }
2109 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002110 params.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002111 supportedWhiteBalance);
2112 }
2113
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002114 k.mParameters.effectMode = ANDROID_CONTROL_EFFECT_OFF;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002115 params.set(CameraParameters::KEY_EFFECT,
2116 CameraParameters::EFFECT_NONE);
2117
2118 camera_metadata_entry_t availableEffects =
2119 staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
2120 if (!availableEffects.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002121 {
2122 String8 supportedEffects;
2123 bool addComma = false;
2124 for (size_t i=0; i < availableEffects.count; i++) {
2125 if (addComma) supportedEffects += ",";
2126 addComma = true;
2127 switch (availableEffects.data.u8[i]) {
2128 case ANDROID_CONTROL_EFFECT_OFF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002129 supportedEffects +=
2130 CameraParameters::EFFECT_NONE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002131 break;
2132 case ANDROID_CONTROL_EFFECT_MONO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002133 supportedEffects +=
2134 CameraParameters::EFFECT_MONO;
2135 break;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002136 case ANDROID_CONTROL_EFFECT_NEGATIVE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002137 supportedEffects +=
2138 CameraParameters::EFFECT_NEGATIVE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002139 break;
2140 case ANDROID_CONTROL_EFFECT_SOLARIZE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002141 supportedEffects +=
2142 CameraParameters::EFFECT_SOLARIZE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002143 break;
2144 case ANDROID_CONTROL_EFFECT_SEPIA:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002145 supportedEffects +=
2146 CameraParameters::EFFECT_SEPIA;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002147 break;
2148 case ANDROID_CONTROL_EFFECT_POSTERIZE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002149 supportedEffects +=
2150 CameraParameters::EFFECT_POSTERIZE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002151 break;
2152 case ANDROID_CONTROL_EFFECT_WHITEBOARD:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002153 supportedEffects +=
2154 CameraParameters::EFFECT_WHITEBOARD;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002155 break;
2156 case ANDROID_CONTROL_EFFECT_BLACKBOARD:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002157 supportedEffects +=
2158 CameraParameters::EFFECT_BLACKBOARD;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002159 break;
2160 case ANDROID_CONTROL_EFFECT_AQUA:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002161 supportedEffects +=
2162 CameraParameters::EFFECT_AQUA;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002163 break;
2164 default:
2165 ALOGW("%s: Camera %d: Unknown effect value: %d",
2166 __FUNCTION__, mCameraId, availableEffects.data.u8[i]);
2167 addComma = false;
2168 break;
2169 }
2170 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002171 params.set(CameraParameters::KEY_SUPPORTED_EFFECTS, supportedEffects);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002172 }
2173
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002174 k.mParameters.antibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002175 params.set(CameraParameters::KEY_ANTIBANDING,
2176 CameraParameters::ANTIBANDING_AUTO);
2177
2178 camera_metadata_entry_t availableAntibandingModes =
2179 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
2180 if (!availableAntibandingModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002181 {
2182 String8 supportedAntibanding;
2183 bool addComma = false;
2184 for (size_t i=0; i < availableAntibandingModes.count; i++) {
2185 if (addComma) supportedAntibanding += ",";
2186 addComma = true;
2187 switch (availableAntibandingModes.data.u8[i]) {
2188 case ANDROID_CONTROL_AE_ANTIBANDING_OFF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002189 supportedAntibanding +=
2190 CameraParameters::ANTIBANDING_OFF;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002191 break;
2192 case ANDROID_CONTROL_AE_ANTIBANDING_50HZ:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002193 supportedAntibanding +=
2194 CameraParameters::ANTIBANDING_50HZ;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002195 break;
2196 case ANDROID_CONTROL_AE_ANTIBANDING_60HZ:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002197 supportedAntibanding +=
2198 CameraParameters::ANTIBANDING_60HZ;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002199 break;
2200 case ANDROID_CONTROL_AE_ANTIBANDING_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002201 supportedAntibanding +=
2202 CameraParameters::ANTIBANDING_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002203 break;
2204 default:
2205 ALOGW("%s: Camera %d: Unknown antibanding value: %d",
2206 __FUNCTION__, mCameraId,
2207 availableAntibandingModes.data.u8[i]);
2208 addComma = false;
2209 break;
2210 }
2211 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002212 params.set(CameraParameters::KEY_SUPPORTED_ANTIBANDING,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002213 supportedAntibanding);
2214 }
2215
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002216 k.mParameters.sceneMode = ANDROID_CONTROL_OFF;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002217 params.set(CameraParameters::KEY_SCENE_MODE,
2218 CameraParameters::SCENE_MODE_AUTO);
2219
2220 camera_metadata_entry_t availableSceneModes =
2221 staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
2222 if (!availableSceneModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002223 {
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002224 String8 supportedSceneModes(CameraParameters::SCENE_MODE_AUTO);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002225 bool addComma = true;
2226 bool noSceneModes = false;
2227 for (size_t i=0; i < availableSceneModes.count; i++) {
2228 if (addComma) supportedSceneModes += ",";
2229 addComma = true;
2230 switch (availableSceneModes.data.u8[i]) {
2231 case ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED:
2232 noSceneModes = true;
2233 break;
2234 case ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY:
2235 // Not in old API
2236 addComma = false;
2237 break;
2238 case ANDROID_CONTROL_SCENE_MODE_ACTION:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002239 supportedSceneModes +=
2240 CameraParameters::SCENE_MODE_ACTION;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002241 break;
2242 case ANDROID_CONTROL_SCENE_MODE_PORTRAIT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002243 supportedSceneModes +=
2244 CameraParameters::SCENE_MODE_PORTRAIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002245 break;
2246 case ANDROID_CONTROL_SCENE_MODE_LANDSCAPE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002247 supportedSceneModes +=
2248 CameraParameters::SCENE_MODE_LANDSCAPE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002249 break;
2250 case ANDROID_CONTROL_SCENE_MODE_NIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002251 supportedSceneModes +=
2252 CameraParameters::SCENE_MODE_NIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002253 break;
2254 case ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002255 supportedSceneModes +=
2256 CameraParameters::SCENE_MODE_NIGHT_PORTRAIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002257 break;
2258 case ANDROID_CONTROL_SCENE_MODE_THEATRE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002259 supportedSceneModes +=
2260 CameraParameters::SCENE_MODE_THEATRE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002261 break;
2262 case ANDROID_CONTROL_SCENE_MODE_BEACH:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002263 supportedSceneModes +=
2264 CameraParameters::SCENE_MODE_BEACH;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002265 break;
2266 case ANDROID_CONTROL_SCENE_MODE_SNOW:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002267 supportedSceneModes +=
2268 CameraParameters::SCENE_MODE_SNOW;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002269 break;
2270 case ANDROID_CONTROL_SCENE_MODE_SUNSET:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002271 supportedSceneModes +=
2272 CameraParameters::SCENE_MODE_SUNSET;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002273 break;
2274 case ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002275 supportedSceneModes +=
2276 CameraParameters::SCENE_MODE_STEADYPHOTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002277 break;
2278 case ANDROID_CONTROL_SCENE_MODE_FIREWORKS:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002279 supportedSceneModes +=
2280 CameraParameters::SCENE_MODE_FIREWORKS;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002281 break;
2282 case ANDROID_CONTROL_SCENE_MODE_SPORTS:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002283 supportedSceneModes +=
2284 CameraParameters::SCENE_MODE_SPORTS;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002285 break;
2286 case ANDROID_CONTROL_SCENE_MODE_PARTY:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002287 supportedSceneModes +=
2288 CameraParameters::SCENE_MODE_PARTY;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002289 break;
2290 case ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002291 supportedSceneModes +=
2292 CameraParameters::SCENE_MODE_CANDLELIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002293 break;
2294 case ANDROID_CONTROL_SCENE_MODE_BARCODE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002295 supportedSceneModes +=
2296 CameraParameters::SCENE_MODE_BARCODE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002297 break;
2298 default:
2299 ALOGW("%s: Camera %d: Unknown scene mode value: %d",
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002300 __FUNCTION__, mCameraId,
2301 availableSceneModes.data.u8[i]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002302 addComma = false;
2303 break;
2304 }
2305 }
2306 if (!noSceneModes) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002307 params.set(CameraParameters::KEY_SUPPORTED_SCENE_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002308 supportedSceneModes);
2309 }
2310 }
2311
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002312 camera_metadata_entry_t flashAvailable =
2313 staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
2314 if (!flashAvailable.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002315
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002316 camera_metadata_entry_t availableAeModes =
2317 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
2318 if (!availableAeModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002319
2320 if (flashAvailable.data.u8[0]) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002321 k.mParameters.flashMode = Parameters::FLASH_MODE_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002322 params.set(CameraParameters::KEY_FLASH_MODE,
2323 CameraParameters::FLASH_MODE_AUTO);
2324
2325 String8 supportedFlashModes(CameraParameters::FLASH_MODE_OFF);
2326 supportedFlashModes = supportedFlashModes +
2327 "," + CameraParameters::FLASH_MODE_AUTO +
2328 "," + CameraParameters::FLASH_MODE_ON +
2329 "," + CameraParameters::FLASH_MODE_TORCH;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002330 for (size_t i=0; i < availableAeModes.count; i++) {
2331 if (availableAeModes.data.u8[i] ==
2332 ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002333 supportedFlashModes = supportedFlashModes + "," +
2334 CameraParameters::FLASH_MODE_RED_EYE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002335 break;
2336 }
2337 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002338 params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002339 supportedFlashModes);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002340 } else {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002341 k.mParameters.flashMode = Parameters::FLASH_MODE_OFF;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002342 params.set(CameraParameters::KEY_FLASH_MODE,
2343 CameraParameters::FLASH_MODE_OFF);
2344 params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
2345 CameraParameters::FLASH_MODE_OFF);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002346 }
2347
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002348 camera_metadata_entry_t minFocusDistance =
2349 staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE, 1, 1);
2350 if (!minFocusDistance.count) return NO_INIT;
2351
2352 camera_metadata_entry_t availableAfModes =
2353 staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
2354 if (!availableAfModes.count) return NO_INIT;
2355
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002356 if (minFocusDistance.data.f[0] == 0) {
2357 // Fixed-focus lens
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002358 k.mParameters.focusMode = Parameters::FOCUS_MODE_FIXED;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002359 params.set(CameraParameters::KEY_FOCUS_MODE,
2360 CameraParameters::FOCUS_MODE_FIXED);
2361 params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
2362 CameraParameters::FOCUS_MODE_FIXED);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002363 } else {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002364 k.mParameters.focusMode = Parameters::FOCUS_MODE_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002365 params.set(CameraParameters::KEY_FOCUS_MODE,
2366 CameraParameters::FOCUS_MODE_AUTO);
2367 String8 supportedFocusModes(CameraParameters::FOCUS_MODE_FIXED);
2368 supportedFocusModes = supportedFocusModes + "," +
2369 CameraParameters::FOCUS_MODE_INFINITY;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002370 bool addComma = true;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002371
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002372 for (size_t i=0; i < availableAfModes.count; i++) {
2373 if (addComma) supportedFocusModes += ",";
2374 addComma = true;
2375 switch (availableAfModes.data.u8[i]) {
2376 case ANDROID_CONTROL_AF_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002377 supportedFocusModes +=
2378 CameraParameters::FOCUS_MODE_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002379 break;
2380 case ANDROID_CONTROL_AF_MACRO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002381 supportedFocusModes +=
2382 CameraParameters::FOCUS_MODE_MACRO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002383 break;
2384 case ANDROID_CONTROL_AF_CONTINUOUS_VIDEO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002385 supportedFocusModes +=
2386 CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002387 break;
2388 case ANDROID_CONTROL_AF_CONTINUOUS_PICTURE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002389 supportedFocusModes +=
2390 CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002391 break;
2392 case ANDROID_CONTROL_AF_EDOF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002393 supportedFocusModes +=
2394 CameraParameters::FOCUS_MODE_EDOF;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002395 break;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002396 // Not supported in old API
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002397 case ANDROID_CONTROL_AF_OFF:
2398 addComma = false;
2399 break;
2400 default:
2401 ALOGW("%s: Camera %d: Unknown AF mode value: %d",
2402 __FUNCTION__, mCameraId, availableAfModes.data.u8[i]);
2403 addComma = false;
2404 break;
2405 }
2406 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002407 params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002408 supportedFocusModes);
2409 }
2410
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002411 camera_metadata_entry_t max3aRegions =
2412 staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1);
2413 if (!max3aRegions.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002414
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002415 params.set(CameraParameters::KEY_MAX_NUM_FOCUS_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002416 max3aRegions.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002417 params.set(CameraParameters::KEY_FOCUS_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002418 "(0,0,0,0,0)");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002419 k.mParameters.focusingAreas.clear();
2420 k.mParameters.focusingAreas.add(Parameters::Area(0,0,0,0,0));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002421
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002422 camera_metadata_entry_t availableFocalLengths =
2423 staticInfo(ANDROID_LENS_AVAILABLE_FOCAL_LENGTHS);
2424 if (!availableFocalLengths.count) return NO_INIT;
2425
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002426 float minFocalLength = availableFocalLengths.data.f[0];
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002427 params.setFloat(CameraParameters::KEY_FOCAL_LENGTH, minFocalLength);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002428
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002429 camera_metadata_entry_t sensorSize =
2430 staticInfo(ANDROID_SENSOR_PHYSICAL_SIZE, 2, 2);
2431 if (!sensorSize.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002432
2433 // The fields of view here assume infinity focus, maximum wide angle
2434 float horizFov = 180 / M_PI *
2435 2 * atanf(sensorSize.data.f[0] / (2 * minFocalLength));
2436 float vertFov = 180 / M_PI *
2437 2 * atanf(sensorSize.data.f[1] / (2 * minFocalLength));
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002438 params.setFloat(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, horizFov);
2439 params.setFloat(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, vertFov);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002440
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002441 k.mParameters.exposureCompensation = 0;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002442 params.set(CameraParameters::KEY_EXPOSURE_COMPENSATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002443 k.mParameters.exposureCompensation);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002444
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002445 camera_metadata_entry_t exposureCompensationRange =
2446 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE, 2, 2);
2447 if (!exposureCompensationRange.count) return NO_INIT;
2448
2449 params.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002450 exposureCompensationRange.data.i32[1]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002451 params.set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002452 exposureCompensationRange.data.i32[0]);
2453
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002454 camera_metadata_entry_t exposureCompensationStep =
2455 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_STEP, 1, 1);
2456 if (!exposureCompensationStep.count) return NO_INIT;
2457
2458 params.setFloat(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP,
Eino-Ville Talvalad6f8e082012-08-02 16:00:35 -07002459 (float)exposureCompensationStep.data.r[0].numerator /
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002460 exposureCompensationStep.data.r[0].denominator);
2461
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002462 k.mParameters.autoExposureLock = false;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002463 params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK,
2464 CameraParameters::FALSE);
2465 params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED,
2466 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002467
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002468 k.mParameters.autoWhiteBalanceLock = false;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002469 params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK,
2470 CameraParameters::FALSE);
2471 params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED,
2472 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002473
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002474 k.mParameters.meteringAreas.add(Parameters::Area(0, 0, 0, 0, 0));
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002475 params.set(CameraParameters::KEY_MAX_NUM_METERING_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002476 max3aRegions.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002477 params.set(CameraParameters::KEY_METERING_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002478 "(0,0,0,0,0)");
2479
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002480 k.mParameters.zoom = 0;
2481 params.set(CameraParameters::KEY_ZOOM, k.mParameters.zoom);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002482 params.set(CameraParameters::KEY_MAX_ZOOM, NUM_ZOOM_STEPS - 1);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002483
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002484 camera_metadata_entry_t maxDigitalZoom =
2485 staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM, 1, 1);
2486 if (!maxDigitalZoom.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002487
2488 {
2489 String8 zoomRatios;
2490 float zoom = 1.f;
2491 float zoomIncrement = (maxDigitalZoom.data.f[0] - zoom) /
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002492 (NUM_ZOOM_STEPS-1);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002493 bool addComma = false;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002494 for (size_t i=0; i < NUM_ZOOM_STEPS; i++) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002495 if (addComma) zoomRatios += ",";
2496 addComma = true;
2497 zoomRatios += String8::format("%d", static_cast<int>(zoom * 100));
2498 zoom += zoomIncrement;
2499 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002500 params.set(CameraParameters::KEY_ZOOM_RATIOS, zoomRatios);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002501 }
2502
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002503 params.set(CameraParameters::KEY_ZOOM_SUPPORTED,
2504 CameraParameters::TRUE);
2505 params.set(CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED,
2506 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002507
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002508 params.set(CameraParameters::KEY_FOCUS_DISTANCES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002509 "Infinity,Infinity,Infinity");
2510
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002511 camera_metadata_entry_t maxFacesDetected =
2512 staticInfo(ANDROID_STATS_MAX_FACE_COUNT, 1, 1);
2513 params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002514 maxFacesDetected.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002515 params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002516 0);
2517
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002518 params.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT,
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002519 CameraParameters::PIXEL_FORMAT_ANDROID_OPAQUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002520
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002521 params.set(CameraParameters::KEY_RECORDING_HINT,
2522 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002523
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002524 params.set(CameraParameters::KEY_VIDEO_SNAPSHOT_SUPPORTED,
2525 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002526
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002527 params.set(CameraParameters::KEY_VIDEO_STABILIZATION,
2528 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002529
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002530 camera_metadata_entry_t availableVideoStabilizationModes =
2531 staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
2532 if (!availableVideoStabilizationModes.count) return NO_INIT;
2533
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002534 if (availableVideoStabilizationModes.count > 1) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002535 params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
2536 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002537 } else {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002538 params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
2539 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002540 }
2541
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07002542 // Set up initial state for non-Camera.Parameters state variables
2543
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002544 k.mParameters.storeMetadataInBuffers = true;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07002545 k.mParameters.playShutterSound = true;
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002546
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002547 k.mParameters.paramsFlattened = params.flatten();
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002548
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002549 return OK;
2550}
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07002551
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002552status_t Camera2Client::updatePreviewStream(const Parameters &params) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002553 ATRACE_CALL();
2554 status_t res;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002555
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002556 if (mPreviewStreamId != NO_STREAM) {
2557 // Check if stream parameters have to change
2558 uint32_t currentWidth, currentHeight;
2559 res = mDevice->getStreamInfo(mPreviewStreamId,
2560 &currentWidth, &currentHeight, 0);
2561 if (res != OK) {
2562 ALOGE("%s: Camera %d: Error querying preview stream info: "
2563 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2564 return res;
2565 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002566 if (currentWidth != (uint32_t)params.previewWidth ||
2567 currentHeight != (uint32_t)params.previewHeight) {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -07002568 ALOGV("%s: Camera %d: Preview size switch: %d x %d -> %d x %d",
2569 __FUNCTION__, mCameraId, currentWidth, currentHeight,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002570 params.previewWidth, params.previewHeight);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002571 res = mDevice->waitUntilDrained();
2572 if (res != OK) {
2573 ALOGE("%s: Camera %d: Error waiting for preview to drain: "
2574 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2575 return res;
2576 }
2577 res = mDevice->deleteStream(mPreviewStreamId);
2578 if (res != OK) {
2579 ALOGE("%s: Camera %d: Unable to delete old output stream "
2580 "for preview: %s (%d)", __FUNCTION__, mCameraId,
2581 strerror(-res), res);
2582 return res;
2583 }
2584 mPreviewStreamId = NO_STREAM;
2585 }
2586 }
2587
2588 if (mPreviewStreamId == NO_STREAM) {
2589 res = mDevice->createStream(mPreviewWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002590 params.previewWidth, params.previewHeight,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002591 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0,
2592 &mPreviewStreamId);
2593 if (res != OK) {
2594 ALOGE("%s: Camera %d: Unable to create preview stream: %s (%d)",
2595 __FUNCTION__, mCameraId, strerror(-res), res);
2596 return res;
2597 }
2598 }
2599
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07002600 res = mDevice->setStreamTransform(mPreviewStreamId,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002601 params.previewTransform);
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07002602 if (res != OK) {
2603 ALOGE("%s: Camera %d: Unable to set preview stream transform: "
2604 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2605 return res;
2606 }
2607
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002608 return OK;
2609}
2610
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002611status_t Camera2Client::updatePreviewRequest(const Parameters &params) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07002612 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002613 status_t res;
2614 if (mPreviewRequest == NULL) {
2615 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
2616 &mPreviewRequest);
2617 if (res != OK) {
2618 ALOGE("%s: Camera %d: Unable to create default preview request: "
2619 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2620 return res;
2621 }
2622 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002623
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002624 res = updateRequestCommon(mPreviewRequest, params);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002625 if (res != OK) {
2626 ALOGE("%s: Camera %d: Unable to update common entries of preview "
2627 "request: %s (%d)", __FUNCTION__, mCameraId,
2628 strerror(-res), res);
2629 return res;
2630 }
2631
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002632 return OK;
2633}
2634
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002635status_t Camera2Client::updateCaptureStream(const Parameters &params) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002636 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002637 status_t res;
2638 // Find out buffer size for JPEG
2639 camera_metadata_entry_t maxJpegSize =
2640 staticInfo(ANDROID_JPEG_MAX_SIZE);
2641 if (maxJpegSize.count == 0) {
2642 ALOGE("%s: Camera %d: Can't find ANDROID_JPEG_MAX_SIZE!",
2643 __FUNCTION__, mCameraId);
2644 return INVALID_OPERATION;
2645 }
2646
2647 if (mCaptureConsumer == 0) {
2648 // Create CPU buffer queue endpoint
2649 mCaptureConsumer = new CpuConsumer(1);
2650 mCaptureConsumer->setFrameAvailableListener(new CaptureWaiter(this));
2651 mCaptureConsumer->setName(String8("Camera2Client::CaptureConsumer"));
2652 mCaptureWindow = new SurfaceTextureClient(
2653 mCaptureConsumer->getProducerInterface());
2654 // Create memory for API consumption
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002655 mCaptureHeap = new Camera2Heap(maxJpegSize.data.i32[0], 1,
2656 "Camera2Client::CaptureHeap");
2657 if (mCaptureHeap->mHeap->getSize() == 0) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002658 ALOGE("%s: Camera %d: Unable to allocate memory for capture",
2659 __FUNCTION__, mCameraId);
2660 return NO_MEMORY;
2661 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002662 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002663
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002664 if (mCaptureStreamId != NO_STREAM) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002665 // Check if stream parameters have to change
2666 uint32_t currentWidth, currentHeight;
2667 res = mDevice->getStreamInfo(mCaptureStreamId,
2668 &currentWidth, &currentHeight, 0);
2669 if (res != OK) {
2670 ALOGE("%s: Camera %d: Error querying capture output stream info: "
2671 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2672 return res;
2673 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002674 if (currentWidth != (uint32_t)params.pictureWidth ||
2675 currentHeight != (uint32_t)params.pictureHeight) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002676 res = mDevice->deleteStream(mCaptureStreamId);
2677 if (res != OK) {
2678 ALOGE("%s: Camera %d: Unable to delete old output stream "
2679 "for capture: %s (%d)", __FUNCTION__, mCameraId,
2680 strerror(-res), res);
2681 return res;
2682 }
2683 mCaptureStreamId = NO_STREAM;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002684 }
2685 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002686
2687 if (mCaptureStreamId == NO_STREAM) {
2688 // Create stream for HAL production
2689 res = mDevice->createStream(mCaptureWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002690 params.pictureWidth, params.pictureHeight,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002691 HAL_PIXEL_FORMAT_BLOB, maxJpegSize.data.i32[0],
2692 &mCaptureStreamId);
2693 if (res != OK) {
2694 ALOGE("%s: Camera %d: Can't create output stream for capture: "
2695 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2696 return res;
2697 }
2698
2699 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002700 return OK;
2701}
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002702
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002703status_t Camera2Client::updateCaptureRequest(const Parameters &params) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002704 ATRACE_CALL();
2705 status_t res;
2706 if (mCaptureRequest == NULL) {
2707 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_STILL_CAPTURE,
2708 &mCaptureRequest);
2709 if (res != OK) {
2710 ALOGE("%s: Camera %d: Unable to create default still image request:"
2711 " %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2712 return res;
2713 }
2714 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002715
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002716 res = updateRequestCommon(mCaptureRequest, params);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002717 if (res != OK) {
2718 ALOGE("%s: Camera %d: Unable to update common entries of capture "
2719 "request: %s (%d)", __FUNCTION__, mCameraId,
2720 strerror(-res), res);
2721 return res;
2722 }
2723
2724 res = updateEntry(mCaptureRequest,
2725 ANDROID_JPEG_THUMBNAIL_SIZE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002726 params.jpegThumbSize, 2);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002727 if (res != OK) return res;
2728 res = updateEntry(mCaptureRequest,
2729 ANDROID_JPEG_THUMBNAIL_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002730 &params.jpegThumbQuality, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002731 if (res != OK) return res;
2732 res = updateEntry(mCaptureRequest,
2733 ANDROID_JPEG_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002734 &params.jpegQuality, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002735 if (res != OK) return res;
2736 res = updateEntry(mCaptureRequest,
2737 ANDROID_JPEG_ORIENTATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002738 &params.jpegRotation, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002739 if (res != OK) return res;
2740
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002741 if (params.gpsEnabled) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002742 res = updateEntry(mCaptureRequest,
2743 ANDROID_JPEG_GPS_COORDINATES,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002744 params.gpsCoordinates, 3);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002745 if (res != OK) return res;
2746 res = updateEntry(mCaptureRequest,
2747 ANDROID_JPEG_GPS_TIMESTAMP,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002748 &params.gpsTimestamp, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002749 if (res != OK) return res;
2750 res = updateEntry(mCaptureRequest,
2751 ANDROID_JPEG_GPS_PROCESSING_METHOD,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002752 params.gpsProcessingMethod.string(),
2753 params.gpsProcessingMethod.size());
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002754 if (res != OK) return res;
2755 } else {
2756 res = deleteEntry(mCaptureRequest,
2757 ANDROID_JPEG_GPS_COORDINATES);
2758 if (res != OK) return res;
2759 res = deleteEntry(mCaptureRequest,
2760 ANDROID_JPEG_GPS_TIMESTAMP);
2761 if (res != OK) return res;
2762 res = deleteEntry(mCaptureRequest,
2763 ANDROID_JPEG_GPS_PROCESSING_METHOD);
2764 if (res != OK) return res;
2765 }
2766
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002767 return OK;
2768}
2769
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002770status_t Camera2Client::updateRecordingRequest(const Parameters &params) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002771 ATRACE_CALL();
2772 status_t res;
2773 if (mRecordingRequest == NULL) {
2774 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_VIDEO_RECORD,
2775 &mRecordingRequest);
2776 if (res != OK) {
2777 ALOGE("%s: Camera %d: Unable to create default recording request:"
2778 " %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2779 return res;
2780 }
2781 }
2782
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002783 res = updateRequestCommon(mRecordingRequest, params);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002784 if (res != OK) {
2785 ALOGE("%s: Camera %d: Unable to update common entries of recording "
2786 "request: %s (%d)", __FUNCTION__, mCameraId,
2787 strerror(-res), res);
2788 return res;
2789 }
2790
2791 return OK;
2792}
2793
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002794status_t Camera2Client::updateRecordingStream(const Parameters &params) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002795 status_t res;
2796
2797 if (mRecordingConsumer == 0) {
2798 // Create CPU buffer queue endpoint
James Dong983cf232012-08-01 16:39:55 -07002799 mRecordingConsumer = new MediaConsumer(mRecordingHeapCount);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002800 mRecordingConsumer->setFrameAvailableListener(new RecordingWaiter(this));
2801 mRecordingConsumer->setName(String8("Camera2Client::RecordingConsumer"));
2802 mRecordingWindow = new SurfaceTextureClient(
2803 mRecordingConsumer->getProducerInterface());
2804 // Allocate memory later, since we don't know buffer size until receipt
2805 }
2806
2807 if (mRecordingStreamId != NO_STREAM) {
2808 // Check if stream parameters have to change
2809 uint32_t currentWidth, currentHeight;
2810 res = mDevice->getStreamInfo(mRecordingStreamId,
2811 &currentWidth, &currentHeight, 0);
2812 if (res != OK) {
2813 ALOGE("%s: Camera %d: Error querying recording output stream info: "
2814 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2815 return res;
2816 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002817 if (currentWidth != (uint32_t)params.videoWidth ||
2818 currentHeight != (uint32_t)params.videoHeight) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002819 // TODO: Should wait to be sure previous recording has finished
2820 res = mDevice->deleteStream(mRecordingStreamId);
2821 if (res != OK) {
2822 ALOGE("%s: Camera %d: Unable to delete old output stream "
2823 "for recording: %s (%d)", __FUNCTION__, mCameraId,
2824 strerror(-res), res);
2825 return res;
2826 }
2827 mRecordingStreamId = NO_STREAM;
2828 }
2829 }
2830
2831 if (mRecordingStreamId == NO_STREAM) {
2832 res = mDevice->createStream(mRecordingWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002833 params.videoWidth, params.videoHeight,
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002834 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0, &mRecordingStreamId);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002835 if (res != OK) {
2836 ALOGE("%s: Camera %d: Can't create output stream for recording: "
2837 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2838 return res;
2839 }
2840 }
2841
2842 return OK;
2843}
2844
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002845status_t Camera2Client::updateRequestCommon(camera_metadata_t *request,
2846 const Parameters &params) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002847 ATRACE_CALL();
2848 status_t res;
2849 res = updateEntry(request,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002850 ANDROID_CONTROL_AE_TARGET_FPS_RANGE, params.previewFpsRange, 2);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002851 if (res != OK) return res;
2852
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002853 uint8_t wbMode = params.autoWhiteBalanceLock ?
2854 ANDROID_CONTROL_AWB_LOCKED : params.wbMode;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002855 res = updateEntry(request,
2856 ANDROID_CONTROL_AWB_MODE, &wbMode, 1);
2857 if (res != OK) return res;
2858 res = updateEntry(request,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002859 ANDROID_CONTROL_EFFECT_MODE, &params.effectMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002860 if (res != OK) return res;
2861 res = updateEntry(request,
2862 ANDROID_CONTROL_AE_ANTIBANDING_MODE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002863 &params.antibandingMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002864 if (res != OK) return res;
2865
2866 uint8_t controlMode =
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002867 (params.sceneMode == ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED) ?
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002868 ANDROID_CONTROL_AUTO : ANDROID_CONTROL_USE_SCENE_MODE;
2869 res = updateEntry(request,
2870 ANDROID_CONTROL_MODE, &controlMode, 1);
2871 if (res != OK) return res;
2872 if (controlMode == ANDROID_CONTROL_USE_SCENE_MODE) {
2873 res = updateEntry(request,
2874 ANDROID_CONTROL_SCENE_MODE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002875 &params.sceneMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002876 if (res != OK) return res;
2877 }
2878
2879 uint8_t flashMode = ANDROID_FLASH_OFF;
2880 uint8_t aeMode;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002881 switch (params.flashMode) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002882 case Parameters::FLASH_MODE_OFF:
2883 aeMode = ANDROID_CONTROL_AE_ON; break;
2884 case Parameters::FLASH_MODE_AUTO:
2885 aeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH; break;
2886 case Parameters::FLASH_MODE_ON:
2887 aeMode = ANDROID_CONTROL_AE_ON_ALWAYS_FLASH; break;
2888 case Parameters::FLASH_MODE_TORCH:
2889 aeMode = ANDROID_CONTROL_AE_ON;
2890 flashMode = ANDROID_FLASH_TORCH;
2891 break;
2892 case Parameters::FLASH_MODE_RED_EYE:
2893 aeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE; break;
2894 default:
2895 ALOGE("%s: Camera %d: Unknown flash mode %d", __FUNCTION__,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002896 mCameraId, params.flashMode);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002897 return BAD_VALUE;
2898 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002899 if (params.autoExposureLock) aeMode = ANDROID_CONTROL_AE_LOCKED;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002900
2901 res = updateEntry(request,
2902 ANDROID_FLASH_MODE, &flashMode, 1);
2903 if (res != OK) return res;
2904 res = updateEntry(request,
2905 ANDROID_CONTROL_AE_MODE, &aeMode, 1);
2906 if (res != OK) return res;
2907
2908 float focusDistance = 0; // infinity focus in diopters
2909 uint8_t focusMode;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002910 switch (params.focusMode) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002911 case Parameters::FOCUS_MODE_AUTO:
2912 case Parameters::FOCUS_MODE_MACRO:
2913 case Parameters::FOCUS_MODE_CONTINUOUS_VIDEO:
2914 case Parameters::FOCUS_MODE_CONTINUOUS_PICTURE:
2915 case Parameters::FOCUS_MODE_EDOF:
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002916 focusMode = params.focusMode;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002917 break;
2918 case Parameters::FOCUS_MODE_INFINITY:
2919 case Parameters::FOCUS_MODE_FIXED:
2920 focusMode = ANDROID_CONTROL_AF_OFF;
2921 break;
2922 default:
2923 ALOGE("%s: Camera %d: Unknown focus mode %d", __FUNCTION__,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002924 mCameraId, params.focusMode);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002925 return BAD_VALUE;
2926 }
2927 res = updateEntry(request,
2928 ANDROID_LENS_FOCUS_DISTANCE, &focusDistance, 1);
2929 if (res != OK) return res;
2930 res = updateEntry(request,
2931 ANDROID_CONTROL_AF_MODE, &focusMode, 1);
2932 if (res != OK) return res;
2933
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002934 size_t focusingAreasSize = params.focusingAreas.size() * 5;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002935 int32_t *focusingAreas = new int32_t[focusingAreasSize];
2936 for (size_t i = 0; i < focusingAreasSize; i += 5) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002937 focusingAreas[i + 0] = params.focusingAreas[i].left;
2938 focusingAreas[i + 1] = params.focusingAreas[i].top;
2939 focusingAreas[i + 2] = params.focusingAreas[i].right;
2940 focusingAreas[i + 3] = params.focusingAreas[i].bottom;
2941 focusingAreas[i + 4] = params.focusingAreas[i].weight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002942 }
2943 res = updateEntry(request,
2944 ANDROID_CONTROL_AF_REGIONS, focusingAreas,focusingAreasSize);
2945 if (res != OK) return res;
2946 delete[] focusingAreas;
2947
2948 res = updateEntry(request,
2949 ANDROID_CONTROL_AE_EXP_COMPENSATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002950 &params.exposureCompensation, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002951 if (res != OK) return res;
2952
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002953 size_t meteringAreasSize = params.meteringAreas.size() * 5;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002954 int32_t *meteringAreas = new int32_t[meteringAreasSize];
2955 for (size_t i = 0; i < meteringAreasSize; i += 5) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002956 meteringAreas[i + 0] = params.meteringAreas[i].left;
2957 meteringAreas[i + 1] = params.meteringAreas[i].top;
2958 meteringAreas[i + 2] = params.meteringAreas[i].right;
2959 meteringAreas[i + 3] = params.meteringAreas[i].bottom;
2960 meteringAreas[i + 4] = params.meteringAreas[i].weight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002961 }
2962 res = updateEntry(request,
2963 ANDROID_CONTROL_AE_REGIONS, meteringAreas, meteringAreasSize);
2964 if (res != OK) return res;
2965
2966 res = updateEntry(request,
2967 ANDROID_CONTROL_AWB_REGIONS, meteringAreas, meteringAreasSize);
2968 if (res != OK) return res;
2969 delete[] meteringAreas;
2970
2971 // Need to convert zoom index into a crop rectangle. The rectangle is
2972 // chosen to maximize its area on the sensor
2973
2974 camera_metadata_entry_t maxDigitalZoom =
2975 staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM);
2976 float zoomIncrement = (maxDigitalZoom.data.f[0] - 1) /
2977 (NUM_ZOOM_STEPS-1);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002978 float zoomRatio = 1 + zoomIncrement * params.zoom;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002979
2980 camera_metadata_entry_t activePixelArraySize =
2981 staticInfo(ANDROID_SENSOR_ACTIVE_ARRAY_SIZE, 2, 2);
2982 int32_t arrayWidth = activePixelArraySize.data.i32[0];
2983 int32_t arrayHeight = activePixelArraySize.data.i32[1];
2984 float zoomLeft, zoomTop, zoomWidth, zoomHeight;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002985 if (params.previewWidth >= params.previewHeight) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002986 zoomWidth = arrayWidth / zoomRatio;
2987 zoomHeight = zoomWidth *
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002988 params.previewHeight / params.previewWidth;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002989 } else {
2990 zoomHeight = arrayHeight / zoomRatio;
2991 zoomWidth = zoomHeight *
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002992 params.previewWidth / params.previewHeight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002993 }
2994 zoomLeft = (arrayWidth - zoomWidth) / 2;
2995 zoomTop = (arrayHeight - zoomHeight) / 2;
2996
2997 int32_t cropRegion[3] = { zoomLeft, zoomTop, zoomWidth };
2998 res = updateEntry(request,
2999 ANDROID_SCALER_CROP_REGION, cropRegion, 3);
3000 if (res != OK) return res;
3001
3002 // TODO: Decide how to map recordingHint, or whether just to ignore it
3003
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003004 uint8_t vstabMode = params.videoStabilization ?
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003005 ANDROID_CONTROL_VIDEO_STABILIZATION_ON :
3006 ANDROID_CONTROL_VIDEO_STABILIZATION_OFF;
3007 res = updateEntry(request,
3008 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
3009 &vstabMode, 1);
3010 if (res != OK) return res;
3011
3012 return OK;
3013}
3014
3015status_t Camera2Client::updateEntry(camera_metadata_t *buffer,
3016 uint32_t tag, const void *data, size_t data_count) {
3017 camera_metadata_entry_t entry;
3018 status_t res;
3019 res = find_camera_metadata_entry(buffer, tag, &entry);
3020 if (res == NAME_NOT_FOUND) {
3021 res = add_camera_metadata_entry(buffer,
3022 tag, data, data_count);
3023 } else if (res == OK) {
3024 res = update_camera_metadata_entry(buffer,
3025 entry.index, data, data_count, NULL);
3026 }
3027
3028 if (res != OK) {
3029 ALOGE("%s: Unable to update metadata entry %s.%s (%x): %s (%d)",
3030 __FUNCTION__, get_camera_metadata_section_name(tag),
3031 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
3032 }
3033 return res;
3034}
3035
3036status_t Camera2Client::deleteEntry(camera_metadata_t *buffer, uint32_t tag) {
3037 camera_metadata_entry_t entry;
3038 status_t res;
3039 res = find_camera_metadata_entry(buffer, tag, &entry);
3040 if (res == NAME_NOT_FOUND) {
3041 return OK;
3042 } else if (res != OK) {
3043 ALOGE("%s: Error looking for entry %s.%s (%x): %s %d",
3044 __FUNCTION__,
3045 get_camera_metadata_section_name(tag),
3046 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
3047 return res;
3048 }
3049 res = delete_camera_metadata_entry(buffer, entry.index);
3050 if (res != OK) {
3051 ALOGE("%s: Error deleting entry %s.%s (%x): %s %d",
3052 __FUNCTION__,
3053 get_camera_metadata_section_name(tag),
3054 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
3055 }
3056 return res;
3057}
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003058
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07003059int Camera2Client::formatStringToEnum(const char *format) {
3060 return
3061 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422SP) ?
3062 HAL_PIXEL_FORMAT_YCbCr_422_SP : // NV16
3063 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420SP) ?
3064 HAL_PIXEL_FORMAT_YCrCb_420_SP : // NV21
3065 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422I) ?
3066 HAL_PIXEL_FORMAT_YCbCr_422_I : // YUY2
3067 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420P) ?
3068 HAL_PIXEL_FORMAT_YV12 : // YV12
3069 !strcmp(format, CameraParameters::PIXEL_FORMAT_RGB565) ?
3070 HAL_PIXEL_FORMAT_RGB_565 : // RGB565
3071 !strcmp(format, CameraParameters::PIXEL_FORMAT_RGBA8888) ?
3072 HAL_PIXEL_FORMAT_RGBA_8888 : // RGB8888
3073 !strcmp(format, CameraParameters::PIXEL_FORMAT_BAYER_RGGB) ?
3074 HAL_PIXEL_FORMAT_RAW_SENSOR : // Raw sensor data
3075 -1;
3076}
3077
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003078const char* Camera2Client::formatEnumToString(int format) {
3079 const char *fmt;
3080 switch(format) {
3081 case HAL_PIXEL_FORMAT_YCbCr_422_SP: // NV16
3082 fmt = CameraParameters::PIXEL_FORMAT_YUV422SP;
3083 break;
3084 case HAL_PIXEL_FORMAT_YCrCb_420_SP: // NV21
3085 fmt = CameraParameters::PIXEL_FORMAT_YUV420SP;
3086 break;
3087 case HAL_PIXEL_FORMAT_YCbCr_422_I: // YUY2
3088 fmt = CameraParameters::PIXEL_FORMAT_YUV422I;
3089 break;
3090 case HAL_PIXEL_FORMAT_YV12: // YV12
3091 fmt = CameraParameters::PIXEL_FORMAT_YUV420P;
3092 break;
3093 case HAL_PIXEL_FORMAT_RGB_565: // RGB565
3094 fmt = CameraParameters::PIXEL_FORMAT_RGB565;
3095 break;
3096 case HAL_PIXEL_FORMAT_RGBA_8888: // RGBA8888
3097 fmt = CameraParameters::PIXEL_FORMAT_RGBA8888;
3098 break;
3099 case HAL_PIXEL_FORMAT_RAW_SENSOR:
3100 ALOGW("Raw sensor preview format requested.");
3101 fmt = CameraParameters::PIXEL_FORMAT_BAYER_RGGB;
3102 break;
3103 default:
3104 ALOGE("%s: Unknown preview format: %x",
3105 __FUNCTION__, format);
3106 fmt = NULL;
3107 break;
3108 }
3109 return fmt;
3110}
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07003111
3112int Camera2Client::wbModeStringToEnum(const char *wbMode) {
3113 return
3114 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_AUTO) ?
3115 ANDROID_CONTROL_AWB_AUTO :
3116 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_INCANDESCENT) ?
3117 ANDROID_CONTROL_AWB_INCANDESCENT :
3118 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_FLUORESCENT) ?
3119 ANDROID_CONTROL_AWB_FLUORESCENT :
3120 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT) ?
3121 ANDROID_CONTROL_AWB_WARM_FLUORESCENT :
3122 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_DAYLIGHT) ?
3123 ANDROID_CONTROL_AWB_DAYLIGHT :
3124 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT) ?
3125 ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT :
3126 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_TWILIGHT) ?
3127 ANDROID_CONTROL_AWB_TWILIGHT :
3128 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_SHADE) ?
3129 ANDROID_CONTROL_AWB_SHADE :
3130 -1;
3131}
3132
3133int Camera2Client::effectModeStringToEnum(const char *effectMode) {
3134 return
3135 !strcmp(effectMode, CameraParameters::EFFECT_NONE) ?
3136 ANDROID_CONTROL_EFFECT_OFF :
3137 !strcmp(effectMode, CameraParameters::EFFECT_MONO) ?
3138 ANDROID_CONTROL_EFFECT_MONO :
3139 !strcmp(effectMode, CameraParameters::EFFECT_NEGATIVE) ?
3140 ANDROID_CONTROL_EFFECT_NEGATIVE :
3141 !strcmp(effectMode, CameraParameters::EFFECT_SOLARIZE) ?
3142 ANDROID_CONTROL_EFFECT_SOLARIZE :
3143 !strcmp(effectMode, CameraParameters::EFFECT_SEPIA) ?
3144 ANDROID_CONTROL_EFFECT_SEPIA :
3145 !strcmp(effectMode, CameraParameters::EFFECT_POSTERIZE) ?
3146 ANDROID_CONTROL_EFFECT_POSTERIZE :
3147 !strcmp(effectMode, CameraParameters::EFFECT_WHITEBOARD) ?
3148 ANDROID_CONTROL_EFFECT_WHITEBOARD :
3149 !strcmp(effectMode, CameraParameters::EFFECT_BLACKBOARD) ?
3150 ANDROID_CONTROL_EFFECT_BLACKBOARD :
3151 !strcmp(effectMode, CameraParameters::EFFECT_AQUA) ?
3152 ANDROID_CONTROL_EFFECT_AQUA :
3153 -1;
3154}
3155
3156int Camera2Client::abModeStringToEnum(const char *abMode) {
3157 return
3158 !strcmp(abMode, CameraParameters::ANTIBANDING_AUTO) ?
3159 ANDROID_CONTROL_AE_ANTIBANDING_AUTO :
3160 !strcmp(abMode, CameraParameters::ANTIBANDING_OFF) ?
3161 ANDROID_CONTROL_AE_ANTIBANDING_OFF :
3162 !strcmp(abMode, CameraParameters::ANTIBANDING_50HZ) ?
3163 ANDROID_CONTROL_AE_ANTIBANDING_50HZ :
3164 !strcmp(abMode, CameraParameters::ANTIBANDING_60HZ) ?
3165 ANDROID_CONTROL_AE_ANTIBANDING_60HZ :
3166 -1;
3167}
3168
3169int Camera2Client::sceneModeStringToEnum(const char *sceneMode) {
3170 return
3171 !strcmp(sceneMode, CameraParameters::SCENE_MODE_AUTO) ?
3172 ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED :
3173 !strcmp(sceneMode, CameraParameters::SCENE_MODE_ACTION) ?
3174 ANDROID_CONTROL_SCENE_MODE_ACTION :
3175 !strcmp(sceneMode, CameraParameters::SCENE_MODE_PORTRAIT) ?
3176 ANDROID_CONTROL_SCENE_MODE_PORTRAIT :
3177 !strcmp(sceneMode, CameraParameters::SCENE_MODE_LANDSCAPE) ?
3178 ANDROID_CONTROL_SCENE_MODE_LANDSCAPE :
3179 !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT) ?
3180 ANDROID_CONTROL_SCENE_MODE_NIGHT :
3181 !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT_PORTRAIT) ?
3182 ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT :
3183 !strcmp(sceneMode, CameraParameters::SCENE_MODE_THEATRE) ?
3184 ANDROID_CONTROL_SCENE_MODE_THEATRE :
3185 !strcmp(sceneMode, CameraParameters::SCENE_MODE_BEACH) ?
3186 ANDROID_CONTROL_SCENE_MODE_BEACH :
3187 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SNOW) ?
3188 ANDROID_CONTROL_SCENE_MODE_SNOW :
3189 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SUNSET) ?
3190 ANDROID_CONTROL_SCENE_MODE_SUNSET :
3191 !strcmp(sceneMode, CameraParameters::SCENE_MODE_STEADYPHOTO) ?
3192 ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO :
3193 !strcmp(sceneMode, CameraParameters::SCENE_MODE_FIREWORKS) ?
3194 ANDROID_CONTROL_SCENE_MODE_FIREWORKS :
3195 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SPORTS) ?
3196 ANDROID_CONTROL_SCENE_MODE_SPORTS :
3197 !strcmp(sceneMode, CameraParameters::SCENE_MODE_PARTY) ?
3198 ANDROID_CONTROL_SCENE_MODE_PARTY :
3199 !strcmp(sceneMode, CameraParameters::SCENE_MODE_CANDLELIGHT) ?
3200 ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT :
3201 !strcmp(sceneMode, CameraParameters::SCENE_MODE_BARCODE) ?
3202 ANDROID_CONTROL_SCENE_MODE_BARCODE:
3203 -1;
3204}
3205
3206Camera2Client::Parameters::flashMode_t Camera2Client::flashModeStringToEnum(
3207 const char *flashMode) {
3208 return
3209 !strcmp(flashMode, CameraParameters::FLASH_MODE_OFF) ?
3210 Parameters::FLASH_MODE_OFF :
3211 !strcmp(flashMode, CameraParameters::FLASH_MODE_AUTO) ?
3212 Parameters::FLASH_MODE_AUTO :
3213 !strcmp(flashMode, CameraParameters::FLASH_MODE_ON) ?
3214 Parameters::FLASH_MODE_ON :
3215 !strcmp(flashMode, CameraParameters::FLASH_MODE_RED_EYE) ?
3216 Parameters::FLASH_MODE_RED_EYE :
3217 !strcmp(flashMode, CameraParameters::FLASH_MODE_TORCH) ?
3218 Parameters::FLASH_MODE_TORCH :
3219 Parameters::FLASH_MODE_INVALID;
3220}
3221
3222Camera2Client::Parameters::focusMode_t Camera2Client::focusModeStringToEnum(
3223 const char *focusMode) {
3224 return
3225 !strcmp(focusMode, CameraParameters::FOCUS_MODE_AUTO) ?
3226 Parameters::FOCUS_MODE_AUTO :
3227 !strcmp(focusMode, CameraParameters::FOCUS_MODE_INFINITY) ?
3228 Parameters::FOCUS_MODE_INFINITY :
3229 !strcmp(focusMode, CameraParameters::FOCUS_MODE_MACRO) ?
3230 Parameters::FOCUS_MODE_MACRO :
3231 !strcmp(focusMode, CameraParameters::FOCUS_MODE_FIXED) ?
3232 Parameters::FOCUS_MODE_FIXED :
3233 !strcmp(focusMode, CameraParameters::FOCUS_MODE_EDOF) ?
3234 Parameters::FOCUS_MODE_EDOF :
3235 !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO) ?
3236 Parameters::FOCUS_MODE_CONTINUOUS_VIDEO :
3237 !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE) ?
3238 Parameters::FOCUS_MODE_CONTINUOUS_PICTURE :
3239 Parameters::FOCUS_MODE_INVALID;
3240}
3241
3242status_t Camera2Client::parseAreas(const char *areasCStr,
3243 Vector<Parameters::Area> *areas) {
3244 static const size_t NUM_FIELDS = 5;
3245 areas->clear();
3246 if (areasCStr == NULL) {
3247 // If no key exists, use default (0,0,0,0,0)
3248 areas->push();
3249 return OK;
3250 }
3251 String8 areasStr(areasCStr);
3252 ssize_t areaStart = areasStr.find("(", 0) + 1;
3253 while (areaStart != 0) {
3254 const char* area = areasStr.string() + areaStart;
3255 char *numEnd;
3256 int vals[NUM_FIELDS];
3257 for (size_t i = 0; i < NUM_FIELDS; i++) {
3258 errno = 0;
3259 vals[i] = strtol(area, &numEnd, 10);
3260 if (errno || numEnd == area) return BAD_VALUE;
3261 area = numEnd + 1;
3262 }
3263 areas->push(Parameters::Area(
3264 vals[0], vals[1], vals[2], vals[3], vals[4]) );
3265 areaStart = areasStr.find("(", areaStart) + 1;
3266 }
3267 return OK;
3268}
3269
3270status_t Camera2Client::validateAreas(const Vector<Parameters::Area> &areas,
3271 size_t maxRegions) {
3272 // Definition of valid area can be found in
3273 // include/camera/CameraParameters.h
3274 if (areas.size() == 0) return BAD_VALUE;
3275 if (areas.size() == 1) {
3276 if (areas[0].left == 0 &&
3277 areas[0].top == 0 &&
3278 areas[0].right == 0 &&
3279 areas[0].bottom == 0 &&
3280 areas[0].weight == 0) {
3281 // Single (0,0,0,0,0) entry is always valid (== driver decides)
3282 return OK;
3283 }
3284 }
3285 if (areas.size() > maxRegions) {
3286 ALOGE("%s: Too many areas requested: %d",
3287 __FUNCTION__, areas.size());
3288 return BAD_VALUE;
3289 }
3290
3291 for (Vector<Parameters::Area>::const_iterator a = areas.begin();
3292 a != areas.end(); a++) {
3293 if (a->weight < 1 || a->weight > 1000) return BAD_VALUE;
3294 if (a->left < -1000 || a->left > 1000) return BAD_VALUE;
3295 if (a->top < -1000 || a->top > 1000) return BAD_VALUE;
3296 if (a->right < -1000 || a->right > 1000) return BAD_VALUE;
3297 if (a->bottom < -1000 || a->bottom > 1000) return BAD_VALUE;
3298 if (a->left >= a->right) return BAD_VALUE;
3299 if (a->top >= a->bottom) return BAD_VALUE;
3300 }
3301 return OK;
3302}
3303
3304bool Camera2Client::boolFromString(const char *boolStr) {
3305 return !boolStr ? false :
3306 !strcmp(boolStr, CameraParameters::TRUE) ? true :
3307 false;
3308}
3309
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07003310int Camera2Client::degToTransform(int degrees, bool mirror) {
3311 if (!mirror) {
3312 if (degrees == 0) return 0;
3313 else if (degrees == 90) return HAL_TRANSFORM_ROT_90;
3314 else if (degrees == 180) return HAL_TRANSFORM_ROT_180;
3315 else if (degrees == 270) return HAL_TRANSFORM_ROT_270;
3316 } else { // Do mirror (horizontal flip)
3317 if (degrees == 0) { // FLIP_H and ROT_0
3318 return HAL_TRANSFORM_FLIP_H;
3319 } else if (degrees == 90) { // FLIP_H and ROT_90
3320 return HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90;
3321 } else if (degrees == 180) { // FLIP_H and ROT_180
3322 return HAL_TRANSFORM_FLIP_V;
3323 } else if (degrees == 270) { // FLIP_H and ROT_270
3324 return HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90;
3325 }
3326 }
3327 ALOGE("%s: Bad input: %d", __FUNCTION__, degrees);
3328 return -1;
3329}
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07003330
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07003331} // namespace android