blob: 21a0547bfa966c1f4af3db30b12953411a9a6271 [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 Talvala8ce89d92012-08-10 08:40:26 -070055 mDeviceInfo(NULL),
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -070056 mPreviewStreamId(NO_STREAM),
Eino-Ville Talvala228a5382012-08-13 12:16:06 -070057 mCallbackStreamId(NO_STREAM),
58 mCallbackHeapId(0),
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -070059 mCaptureStreamId(NO_STREAM),
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -070060 mRecordingStreamId(NO_STREAM),
James Dong983cf232012-08-01 16:39:55 -070061 mRecordingHeapCount(kDefaultRecordingHeapCount)
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070062{
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070063 ATRACE_CALL();
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -070064 ALOGV("%s: Created client for camera %d", __FUNCTION__, cameraId);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070065
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070066 mDevice = new Camera2Device(cameraId);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -070067
68 LockedParameters::Key k(mParameters);
69 k.mParameters.state = DISCONNECTED;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070070}
71
Eino-Ville Talvala3a609142012-07-31 14:36:26 -070072status_t Camera2Client::checkPid(const char* checkLocation) const {
73 int callingPid = getCallingPid();
74 if (callingPid == mClientPid) return NO_ERROR;
75
76 ALOGE("%s: attempt to use a locked camera from a different process"
77 " (old pid %d, new pid %d)", checkLocation, mClientPid, callingPid);
78 return PERMISSION_DENIED;
79}
80
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070081status_t Camera2Client::initialize(camera_module_t *module)
82{
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070083 ATRACE_CALL();
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -070084 ALOGV("%s: Initializing client for camera %d", __FUNCTION__, mCameraId);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070085 status_t res;
86
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -070087 mFrameProcessor = new FrameProcessor(this);
88 String8 frameThreadName = String8::format("Camera2Client[%d]::FrameProcessor",
89 mCameraId);
90 mFrameProcessor->run(frameThreadName.string());
91
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070092 res = mDevice->initialize(module);
93 if (res != OK) {
94 ALOGE("%s: Camera %d: unable to initialize device: %s (%d)",
95 __FUNCTION__, mCameraId, strerror(-res), res);
96 return NO_INIT;
97 }
98
Eino-Ville Talvala174181e2012-08-03 13:53:39 -070099 res = mDevice->setNotifyCallback(this);
100
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700101 res = buildDeviceInfo();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700102 res = buildDefaultParameters();
103 if (res != OK) {
104 ALOGE("%s: Camera %d: unable to build defaults: %s (%d)",
105 __FUNCTION__, mCameraId, strerror(-res), res);
106 return NO_INIT;
107 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -0700108
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700109 if (gLogLevel >= 1) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700110 LockedParameters::Key k(mParameters);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700111 ALOGD("%s: Default parameters converted from camera %d:", __FUNCTION__,
112 mCameraId);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700113 ALOGD("%s", k.mParameters.paramsFlattened.string());
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700114 }
115
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700116 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700117}
118
119Camera2Client::~Camera2Client() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700120 ATRACE_CALL();
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -0700121 ALOGV("%s: Camera %d: Shutting down client.", __FUNCTION__, mCameraId);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700122
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700123 mDestructionStarted = true;
124
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700125 // Rewrite mClientPid to allow shutdown by CameraService
126 mClientPid = getCallingPid();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700127 disconnect();
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -0700128
129 mFrameProcessor->requestExit();
130 ALOGV("%s: Camera %d: Shutdown complete", __FUNCTION__, mCameraId);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700131}
132
133status_t Camera2Client::dump(int fd, const Vector<String16>& args) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700134 String8 result;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700135 result.appendFormat("Client2[%d] (%p) PID: %d, dump:\n",
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700136 mCameraId,
137 getCameraClient()->asBinder().get(),
138 mClientPid);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700139 result.append(" State: ");
140#define CASE_APPEND_ENUM(x) case x: result.append(#x "\n"); break;
141
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700142 const Parameters& p = mParameters.unsafeUnlock();
143
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700144 result.append(getStateName(p.state));
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700145
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700146 result.append("\n Current parameters:\n");
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700147 result.appendFormat(" Preview size: %d x %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700148 p.previewWidth, p.previewHeight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700149 result.appendFormat(" Preview FPS range: %d - %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700150 p.previewFpsRange[0], p.previewFpsRange[1]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700151 result.appendFormat(" Preview HAL pixel format: 0x%x\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700152 p.previewFormat);
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700153 result.appendFormat(" Preview transform: %x\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700154 p.previewTransform);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700155 result.appendFormat(" Picture size: %d x %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700156 p.pictureWidth, p.pictureHeight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700157 result.appendFormat(" Jpeg thumbnail size: %d x %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700158 p.jpegThumbSize[0], p.jpegThumbSize[1]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700159 result.appendFormat(" Jpeg quality: %d, thumbnail quality: %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700160 p.jpegQuality, p.jpegThumbQuality);
161 result.appendFormat(" Jpeg rotation: %d\n", p.jpegRotation);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700162 result.appendFormat(" GPS tags %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700163 p.gpsEnabled ? "enabled" : "disabled");
164 if (p.gpsEnabled) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700165 result.appendFormat(" GPS lat x long x alt: %f x %f x %f\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700166 p.gpsCoordinates[0], p.gpsCoordinates[1],
167 p.gpsCoordinates[2]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700168 result.appendFormat(" GPS timestamp: %lld\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700169 p.gpsTimestamp);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700170 result.appendFormat(" GPS processing method: %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700171 p.gpsProcessingMethod.string());
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700172 }
173
174 result.append(" White balance mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700175 switch (p.wbMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700176 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_AUTO)
177 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_INCANDESCENT)
178 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_FLUORESCENT)
179 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_WARM_FLUORESCENT)
180 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_DAYLIGHT)
181 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT)
182 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_TWILIGHT)
183 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_SHADE)
184 default: result.append("UNKNOWN\n");
185 }
186
187 result.append(" Effect mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700188 switch (p.effectMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700189 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_OFF)
190 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_MONO)
191 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_NEGATIVE)
192 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_SOLARIZE)
193 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_SEPIA)
194 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_POSTERIZE)
195 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_WHITEBOARD)
196 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_BLACKBOARD)
197 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_AQUA)
198 default: result.append("UNKNOWN\n");
199 }
200
201 result.append(" Antibanding mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700202 switch (p.antibandingMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700203 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_AUTO)
204 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_OFF)
205 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_50HZ)
206 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_60HZ)
207 default: result.append("UNKNOWN\n");
208 }
209
210 result.append(" Scene mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700211 switch (p.sceneMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700212 case ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED:
213 result.append("AUTO\n"); break;
214 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_ACTION)
215 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_PORTRAIT)
216 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_LANDSCAPE)
217 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_NIGHT)
218 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT)
219 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_THEATRE)
220 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_BEACH)
221 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SNOW)
222 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SUNSET)
223 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO)
224 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_FIREWORKS)
225 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SPORTS)
226 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_PARTY)
227 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT)
228 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_BARCODE)
229 default: result.append("UNKNOWN\n");
230 }
231
232 result.append(" Flash mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700233 switch (p.flashMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700234 CASE_APPEND_ENUM(Parameters::FLASH_MODE_OFF)
235 CASE_APPEND_ENUM(Parameters::FLASH_MODE_AUTO)
236 CASE_APPEND_ENUM(Parameters::FLASH_MODE_ON)
237 CASE_APPEND_ENUM(Parameters::FLASH_MODE_TORCH)
238 CASE_APPEND_ENUM(Parameters::FLASH_MODE_RED_EYE)
239 CASE_APPEND_ENUM(Parameters::FLASH_MODE_INVALID)
240 default: result.append("UNKNOWN\n");
241 }
242
243 result.append(" Focus mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700244 switch (p.focusMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700245 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_AUTO)
246 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_MACRO)
247 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_CONTINUOUS_VIDEO)
248 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_CONTINUOUS_PICTURE)
249 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_EDOF)
250 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_INFINITY)
251 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_FIXED)
252 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_INVALID)
253 default: result.append("UNKNOWN\n");
254 }
255
256 result.append(" Focusing areas:\n");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700257 for (size_t i = 0; i < p.focusingAreas.size(); i++) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700258 result.appendFormat(" [ (%d, %d, %d, %d), weight %d ]\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700259 p.focusingAreas[i].left,
260 p.focusingAreas[i].top,
261 p.focusingAreas[i].right,
262 p.focusingAreas[i].bottom,
263 p.focusingAreas[i].weight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700264 }
265
266 result.appendFormat(" Exposure compensation index: %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700267 p.exposureCompensation);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700268
269 result.appendFormat(" AE lock %s, AWB lock %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700270 p.autoExposureLock ? "enabled" : "disabled",
271 p.autoWhiteBalanceLock ? "enabled" : "disabled" );
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700272
273 result.appendFormat(" Metering areas:\n");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700274 for (size_t i = 0; i < p.meteringAreas.size(); i++) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700275 result.appendFormat(" [ (%d, %d, %d, %d), weight %d ]\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700276 p.meteringAreas[i].left,
277 p.meteringAreas[i].top,
278 p.meteringAreas[i].right,
279 p.meteringAreas[i].bottom,
280 p.meteringAreas[i].weight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700281 }
282
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700283 result.appendFormat(" Zoom index: %d\n", p.zoom);
284 result.appendFormat(" Video size: %d x %d\n", p.videoWidth,
285 p.videoHeight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700286
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700287 result.appendFormat(" Recording hint is %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700288 p.recordingHint ? "set" : "not set");
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700289
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700290 result.appendFormat(" Video stabilization is %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700291 p.videoStabilization ? "enabled" : "disabled");
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700292
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700293 result.append(" Current streams:\n");
294 result.appendFormat(" Preview stream ID: %d\n", mPreviewStreamId);
295 result.appendFormat(" Capture stream ID: %d\n", mCaptureStreamId);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700296 result.appendFormat(" Recording stream ID: %d\n", mRecordingStreamId);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700297
298 result.append(" Current requests:\n");
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700299 if (mPreviewRequest.entryCount() != 0) {
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700300 result.append(" Preview request:\n");
301 write(fd, result.string(), result.size());
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700302 mPreviewRequest.dump(fd, 2, 6);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700303 } else {
304 result.append(" Preview request: undefined\n");
305 write(fd, result.string(), result.size());
306 }
307
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700308 if (mCaptureRequest.entryCount() != 0) {
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700309 result = " Capture request:\n";
310 write(fd, result.string(), result.size());
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700311 mCaptureRequest.dump(fd, 2, 6);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700312 } else {
313 result = " Capture request: undefined\n";
314 write(fd, result.string(), result.size());
315 }
316
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700317 if (mRecordingRequest.entryCount() != 0) {
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700318 result = " Recording request:\n";
319 write(fd, result.string(), result.size());
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700320 mRecordingRequest.dump(fd, 2, 6);
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700321 } else {
322 result = " Recording request: undefined\n";
323 write(fd, result.string(), result.size());
324 }
325
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -0700326 mFrameProcessor->dump(fd, args);
327
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700328 result = " Device dump:\n";
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700329 write(fd, result.string(), result.size());
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700330
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700331 status_t res = mDevice->dump(fd, args);
332 if (res != OK) {
333 result = String8::format(" Error dumping device: %s (%d)",
334 strerror(-res), res);
335 write(fd, result.string(), result.size());
336 }
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700337
338#undef CASE_APPEND_ENUM
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700339 return NO_ERROR;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700340}
341
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700342const char* Camera2Client::getStateName(State state) {
343#define CASE_ENUM_TO_CHAR(x) case x: return(#x); break;
344 switch(state) {
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700345 CASE_ENUM_TO_CHAR(DISCONNECTED)
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700346 CASE_ENUM_TO_CHAR(STOPPED)
347 CASE_ENUM_TO_CHAR(WAITING_FOR_PREVIEW_WINDOW)
348 CASE_ENUM_TO_CHAR(PREVIEW)
349 CASE_ENUM_TO_CHAR(RECORD)
350 CASE_ENUM_TO_CHAR(STILL_CAPTURE)
351 CASE_ENUM_TO_CHAR(VIDEO_SNAPSHOT)
352 default:
353 return "Unknown state!";
354 break;
355 }
356#undef CASE_ENUM_TO_CHAR
357}
358
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700359// ICamera interface
360
361void Camera2Client::disconnect() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700362 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700363 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700364 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700365 status_t res;
366 if ( (res = checkPid(__FUNCTION__) ) != OK) return;
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700367
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700368 if (mDevice == 0) return;
369
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700370 stopPreviewL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700371
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700372 if (mPreviewStreamId != NO_STREAM) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700373 mDevice->deleteStream(mPreviewStreamId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700374 mPreviewStreamId = NO_STREAM;
375 }
376
377 if (mCaptureStreamId != NO_STREAM) {
378 mDevice->deleteStream(mCaptureStreamId);
379 mCaptureStreamId = NO_STREAM;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700380 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700381
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -0700382 if (mRecordingStreamId != NO_STREAM) {
383 mDevice->deleteStream(mRecordingStreamId);
384 mRecordingStreamId = NO_STREAM;
385 }
386
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700387 if (mCallbackStreamId != NO_STREAM) {
388 mDevice->deleteStream(mCallbackStreamId);
389 mCallbackStreamId = NO_STREAM;
390 }
391
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700392 mDevice.clear();
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700393 LockedParameters::Key k(mParameters);
394 k.mParameters.state = DISCONNECTED;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700395
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700396 if (mDeviceInfo != NULL) {
397 delete mDeviceInfo;
398 mDeviceInfo = NULL;
399 }
400
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700401 CameraService::Client::disconnect();
402}
403
404status_t Camera2Client::connect(const sp<ICameraClient>& client) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700405 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700406 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700407 Mutex::Autolock icl(mICameraLock);
408
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700409 if (mClientPid != 0 && getCallingPid() != mClientPid) {
410 ALOGE("%s: Camera %d: Connection attempt from pid %d; "
411 "current locked to pid %d", __FUNCTION__,
412 mCameraId, getCallingPid(), mClientPid);
413 return BAD_VALUE;
414 }
415
416 mClientPid = getCallingPid();
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700417
418 Mutex::Autolock iccl(mICameraClientLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700419 mCameraClient = client;
420
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700421 LockedParameters::Key k(mParameters);
422 k.mParameters.state = STOPPED;
423
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700424 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700425}
426
427status_t Camera2Client::lock() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700428 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700429 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700430 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700431 ALOGV("%s: Camera %d: Lock call from pid %d; current client pid %d",
432 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700433
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700434 if (mClientPid == 0) {
435 mClientPid = getCallingPid();
436 return OK;
437 }
438
439 if (mClientPid != getCallingPid()) {
440 ALOGE("%s: Camera %d: Lock call from pid %d; currently locked to pid %d",
441 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
442 return EBUSY;
443 }
444
445 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700446}
447
448status_t Camera2Client::unlock() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700449 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700450 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700451 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700452 ALOGV("%s: Camera %d: Unlock call from pid %d; current client pid %d",
453 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700454
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700455 // TODO: Check for uninterruptable conditions
456
457 if (mClientPid == getCallingPid()) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700458 Mutex::Autolock iccl(mICameraClientLock);
459
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700460 mClientPid = 0;
461 mCameraClient.clear();
462 return OK;
463 }
464
465 ALOGE("%s: Camera %d: Unlock call from pid %d; currently locked to pid %d",
466 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
467 return EBUSY;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700468}
469
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700470status_t Camera2Client::setPreviewDisplay(
471 const sp<Surface>& surface) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700472 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700473 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700474 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700475 status_t res;
476 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700477
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700478 sp<IBinder> binder;
479 sp<ANativeWindow> window;
480 if (surface != 0) {
481 binder = surface->asBinder();
482 window = surface;
483 }
484
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700485 return setPreviewWindowL(binder,window);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700486}
487
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700488status_t Camera2Client::setPreviewTexture(
489 const sp<ISurfaceTexture>& surfaceTexture) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700490 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700491 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700492 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700493 status_t res;
494 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700495
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700496 sp<IBinder> binder;
497 sp<ANativeWindow> window;
498 if (surfaceTexture != 0) {
499 binder = surfaceTexture->asBinder();
500 window = new SurfaceTextureClient(surfaceTexture);
501 }
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700502 return setPreviewWindowL(binder, window);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700503}
504
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700505status_t Camera2Client::setPreviewWindowL(const sp<IBinder>& binder,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700506 sp<ANativeWindow> window) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700507 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700508 status_t res;
509
510 if (binder == mPreviewSurface) {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700511 ALOGV("%s: Camera %d: New window is same as old window",
512 __FUNCTION__, mCameraId);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700513 return NO_ERROR;
514 }
515
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700516 LockedParameters::Key k(mParameters);
517 switch (k.mParameters.state) {
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700518 case DISCONNECTED:
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700519 case RECORD:
520 case STILL_CAPTURE:
521 case VIDEO_SNAPSHOT:
522 ALOGE("%s: Camera %d: Cannot set preview display while in state %s",
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700523 __FUNCTION__, mCameraId, getStateName(k.mParameters.state));
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700524 return INVALID_OPERATION;
525 case STOPPED:
526 case WAITING_FOR_PREVIEW_WINDOW:
527 // OK
528 break;
529 case PREVIEW:
530 // Already running preview - need to stop and create a new stream
531 // TODO: Optimize this so that we don't wait for old stream to drain
532 // before spinning up new stream
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700533 mDevice->clearStreamingRequest();
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700534 k.mParameters.state = WAITING_FOR_PREVIEW_WINDOW;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700535 break;
536 }
537
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700538 if (mPreviewStreamId != NO_STREAM) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700539 res = mDevice->waitUntilDrained();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700540 if (res != OK) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700541 ALOGE("%s: Error waiting for preview to drain: %s (%d)",
542 __FUNCTION__, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700543 return res;
544 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700545 res = mDevice->deleteStream(mPreviewStreamId);
546 if (res != OK) {
547 ALOGE("%s: Unable to delete old preview stream: %s (%d)",
548 __FUNCTION__, strerror(-res), res);
549 return res;
550 }
551 mPreviewStreamId = NO_STREAM;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700552 }
553
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700554 mPreviewSurface = binder;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700555 mPreviewWindow = window;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700556
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700557 if (k.mParameters.state == WAITING_FOR_PREVIEW_WINDOW) {
558 return startPreviewL(k.mParameters, false);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700559 }
560
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700561 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700562}
563
564void Camera2Client::setPreviewCallbackFlag(int flag) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700565 ATRACE_CALL();
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700566 ALOGV("%s: Camera %d: Flag 0x%x", __FUNCTION__, mCameraId, flag);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700567 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700568 status_t res;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700569 if ( checkPid(__FUNCTION__) != OK) return;
570
571 LockedParameters::Key k(mParameters);
572 setPreviewCallbackFlagL(k.mParameters, flag);
573}
574
575void Camera2Client::setPreviewCallbackFlagL(Parameters &params, int flag) {
576 status_t res = OK;
577 if (flag & CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) {
578 ALOGV("%s: setting oneshot", __FUNCTION__);
579 params.previewCallbackOneShot = true;
580 }
581 if (params.previewCallbackFlags != (uint32_t)flag) {
582 params.previewCallbackFlags = flag;
583 switch(params.state) {
584 case PREVIEW:
585 res = startPreviewL(params, true);
586 break;
587 case RECORD:
588 case VIDEO_SNAPSHOT:
589 res = startRecordingL(params, true);
590 break;
591 default:
592 break;
593 }
594 if (res != OK) {
595 ALOGE("%s: Camera %d: Unable to refresh request in state %s",
596 __FUNCTION__, mCameraId, getStateName(params.state));
597 }
598 }
599
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700600}
601
602status_t Camera2Client::startPreview() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700603 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700604 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700605 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700606 status_t res;
607 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700608 LockedParameters::Key k(mParameters);
609 return startPreviewL(k.mParameters, false);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700610}
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700611
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700612status_t Camera2Client::startPreviewL(Parameters &params, bool restart) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700613 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700614 status_t res;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700615 if (params.state >= PREVIEW && !restart) {
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700616 ALOGE("%s: Can't start preview in state %s",
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700617 __FUNCTION__, getStateName(params.state));
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700618 return INVALID_OPERATION;
619 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700620
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700621 if (mPreviewWindow == 0) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700622 params.state = WAITING_FOR_PREVIEW_WINDOW;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700623 return OK;
624 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700625 params.state = STOPPED;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700626
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700627 res = updatePreviewStream(params);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700628 if (res != OK) {
629 ALOGE("%s: Camera %d: Unable to update preview stream: %s (%d)",
630 __FUNCTION__, mCameraId, strerror(-res), res);
631 return res;
632 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700633 bool callbacksEnabled = params.previewCallbackFlags &
634 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK;
635 if (callbacksEnabled) {
636 res = updateCallbackStream(params);
637 if (res != OK) {
638 ALOGE("%s: Camera %d: Unable to update callback stream: %s (%d)",
639 __FUNCTION__, mCameraId, strerror(-res), res);
640 return res;
641 }
642 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700643
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700644 if (mPreviewRequest.entryCount() == 0) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700645 res = updatePreviewRequest(params);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700646 if (res != OK) {
647 ALOGE("%s: Camera %d: Unable to create preview request: %s (%d)",
648 __FUNCTION__, mCameraId, strerror(-res), res);
649 return res;
650 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700651 }
652
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700653 if (callbacksEnabled) {
654 uint8_t outputStreams[2] =
655 { mPreviewStreamId, mCallbackStreamId };
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700656 res = mPreviewRequest.update(
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700657 ANDROID_REQUEST_OUTPUT_STREAMS,
658 outputStreams, 2);
659 } else {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700660 uint8_t outputStreams[1] = { mPreviewStreamId };
661 res = mPreviewRequest.update(
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700662 ANDROID_REQUEST_OUTPUT_STREAMS,
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700663 outputStreams, 1);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700664 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700665 if (res != OK) {
666 ALOGE("%s: Camera %d: Unable to set up preview request: %s (%d)",
667 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700668 return res;
669 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700670 res = mPreviewRequest.sort();
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700671 if (res != OK) {
672 ALOGE("%s: Camera %d: Error sorting preview request: %s (%d)",
673 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700674 return res;
675 }
676
677 res = mDevice->setStreamingRequest(mPreviewRequest);
678 if (res != OK) {
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700679 ALOGE("%s: Camera %d: Unable to set preview request to start preview: "
680 "%s (%d)",
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700681 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700682 return res;
683 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700684 params.state = PREVIEW;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700685
686 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700687}
688
689void Camera2Client::stopPreview() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700690 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700691 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700692 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700693 status_t res;
694 if ( (res = checkPid(__FUNCTION__) ) != OK) return;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700695 stopPreviewL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700696}
697
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700698void Camera2Client::stopPreviewL() {
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700699 ATRACE_CALL();
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700700 State state;
701 {
702 LockedParameters::Key k(mParameters);
703 state = k.mParameters.state;
704 }
705
706 switch (state) {
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700707 case DISCONNECTED:
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700708 ALOGE("%s: Camera %d: Call before initialized",
709 __FUNCTION__, mCameraId);
710 break;
711 case STOPPED:
712 break;
713 case STILL_CAPTURE:
714 ALOGE("%s: Camera %d: Cannot stop preview during still capture.",
715 __FUNCTION__, mCameraId);
716 break;
717 case RECORD:
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700718 // no break - identical to preview
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700719 case PREVIEW:
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700720 mDevice->clearStreamingRequest();
Eino-Ville Talvala22671062012-07-20 18:30:37 -0700721 mDevice->waitUntilDrained();
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700722 // no break
723 case WAITING_FOR_PREVIEW_WINDOW: {
724 LockedParameters::Key k(mParameters);
725 k.mParameters.state = STOPPED;
726 commandStopFaceDetectionL(k.mParameters);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700727 break;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700728 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700729 default:
730 ALOGE("%s: Camera %d: Unknown state %d", __FUNCTION__, mCameraId,
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700731 state);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700732 }
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700733}
734
735bool Camera2Client::previewEnabled() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700736 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700737 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700738 status_t res;
739 if ( (res = checkPid(__FUNCTION__) ) != OK) return false;
740
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700741 LockedParameters::Key k(mParameters);
742 return k.mParameters.state == PREVIEW;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700743}
744
745status_t Camera2Client::storeMetaDataInBuffers(bool enabled) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700746 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700747 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700748 status_t res;
749 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
750
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700751 LockedParameters::Key k(mParameters);
752 switch (k.mParameters.state) {
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700753 case RECORD:
754 case VIDEO_SNAPSHOT:
755 ALOGE("%s: Camera %d: Can't be called in state %s",
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700756 __FUNCTION__, mCameraId, getStateName(k.mParameters.state));
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700757 return INVALID_OPERATION;
758 default:
759 // OK
760 break;
761 }
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700762
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700763 k.mParameters.storeMetadataInBuffers = enabled;
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700764
765 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700766}
767
768status_t Camera2Client::startRecording() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700769 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700770 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700771 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700772 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700773 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700774 LockedParameters::Key k(mParameters);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700775
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700776 return startRecordingL(k.mParameters, false);
777}
778
779status_t Camera2Client::startRecordingL(Parameters &params, bool restart) {
780 status_t res;
781 switch (params.state) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700782 case STOPPED:
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700783 res = startPreviewL(params, false);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700784 if (res != OK) return res;
785 break;
786 case PREVIEW:
787 // Ready to go
788 break;
789 case RECORD:
790 case VIDEO_SNAPSHOT:
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700791 // OK to call this when recording is already on, just skip unless
792 // we're looking to restart
793 if (!restart) return OK;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700794 break;
795 default:
796 ALOGE("%s: Camera %d: Can't start recording in state %s",
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700797 __FUNCTION__, mCameraId, getStateName(params.state));
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700798 return INVALID_OPERATION;
799 };
800
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700801 if (!params.storeMetadataInBuffers) {
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700802 ALOGE("%s: Camera %d: Recording only supported in metadata mode, but "
803 "non-metadata recording mode requested!", __FUNCTION__,
804 mCameraId);
805 return INVALID_OPERATION;
806 }
807
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700808 res = updateRecordingStream(params);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700809 if (res != OK) {
810 ALOGE("%s: Camera %d: Unable to update recording stream: %s (%d)",
811 __FUNCTION__, mCameraId, strerror(-res), res);
812 return res;
813 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700814 bool callbacksEnabled = params.previewCallbackFlags &
815 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK;
816 if (callbacksEnabled) {
817 res = updateCallbackStream(params);
818 if (res != OK) {
819 ALOGE("%s: Camera %d: Unable to update callback stream: %s (%d)",
820 __FUNCTION__, mCameraId, strerror(-res), res);
821 return res;
822 }
823 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700824
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700825 if (mRecordingRequest.entryCount() == 0) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700826 res = updateRecordingRequest(params);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700827 if (res != OK) {
828 ALOGE("%s: Camera %d: Unable to create recording request: %s (%d)",
829 __FUNCTION__, mCameraId, strerror(-res), res);
830 return res;
831 }
832 }
833
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700834 if (callbacksEnabled) {
835 uint8_t outputStreams[3] =
836 { mPreviewStreamId, mRecordingStreamId, mCallbackStreamId };
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700837 res = mRecordingRequest.update(
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700838 ANDROID_REQUEST_OUTPUT_STREAMS,
839 outputStreams, 3);
840 } else {
841 uint8_t outputStreams[2] = { mPreviewStreamId, mRecordingStreamId };
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700842 res = mRecordingRequest.update(
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700843 ANDROID_REQUEST_OUTPUT_STREAMS,
844 outputStreams, 2);
845 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700846 if (res != OK) {
847 ALOGE("%s: Camera %d: Unable to set up recording request: %s (%d)",
848 __FUNCTION__, mCameraId, strerror(-res), res);
849 return res;
850 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700851 res = mRecordingRequest.sort();
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700852 if (res != OK) {
853 ALOGE("%s: Camera %d: Error sorting recording request: %s (%d)",
854 __FUNCTION__, mCameraId, strerror(-res), res);
855 return res;
856 }
857
858 res = mDevice->setStreamingRequest(mRecordingRequest);
859 if (res != OK) {
860 ALOGE("%s: Camera %d: Unable to set recording request to start "
861 "recording: %s (%d)", __FUNCTION__, mCameraId,
862 strerror(-res), res);
863 return res;
864 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700865 if (params.state < RECORD) {
866 params.state = RECORD;
867 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700868
869 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700870}
871
872void Camera2Client::stopRecording() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700873 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700874 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700875 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700876 LockedParameters::Key k(mParameters);
877
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700878 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700879 if ( (res = checkPid(__FUNCTION__) ) != OK) return;
880
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700881 switch (k.mParameters.state) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700882 case RECORD:
883 // OK to stop
884 break;
885 case STOPPED:
886 case PREVIEW:
887 case STILL_CAPTURE:
888 case VIDEO_SNAPSHOT:
889 default:
890 ALOGE("%s: Camera %d: Can't stop recording in state %s",
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700891 __FUNCTION__, mCameraId, getStateName(k.mParameters.state));
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700892 return;
893 };
894
895 // Back to preview. Since record can only be reached through preview,
896 // all preview stream setup should be up to date.
897 res = mDevice->setStreamingRequest(mPreviewRequest);
898 if (res != OK) {
899 ALOGE("%s: Camera %d: Unable to switch back to preview request: "
900 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
901 return;
902 }
903
904 // TODO: Should recording heap be freed? Can't do it yet since requests
905 // could still be in flight.
906
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700907 k.mParameters.state = PREVIEW;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700908}
909
910bool Camera2Client::recordingEnabled() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700911 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700912 Mutex::Autolock icl(mICameraLock);
James Dong8da4cd72012-08-04 19:58:07 -0700913
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700914 if ( checkPid(__FUNCTION__) != OK) return false;
915
James Dong8da4cd72012-08-04 19:58:07 -0700916 return recordingEnabledL();
917}
918
919bool Camera2Client::recordingEnabledL() {
920 ATRACE_CALL();
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700921 LockedParameters::Key k(mParameters);
James Dong8da4cd72012-08-04 19:58:07 -0700922
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700923 return (k.mParameters.state == RECORD || k.mParameters.state == VIDEO_SNAPSHOT);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700924}
925
926void Camera2Client::releaseRecordingFrame(const sp<IMemory>& mem) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700927 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700928 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700929 status_t res;
930 if ( checkPid(__FUNCTION__) != OK) return;
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -0700931
932 LockedParameters::Key k(mParameters);
933
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700934 // Make sure this is for the current heap
935 ssize_t offset;
936 size_t size;
937 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
938 if (heap->getHeapID() != mRecordingHeap->mHeap->getHeapID()) {
939 ALOGW("%s: Camera %d: Mismatched heap ID, ignoring release "
940 "(got %x, expected %x)", __FUNCTION__, mCameraId,
941 heap->getHeapID(), mRecordingHeap->mHeap->getHeapID());
942 return;
943 }
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700944 uint8_t *data = (uint8_t*)heap->getBase() + offset;
945 uint32_t type = *(uint32_t*)data;
946 if (type != kMetadataBufferTypeGrallocSource) {
947 ALOGE("%s: Camera %d: Recording frame type invalid (got %x, expected %x)",
948 __FUNCTION__, mCameraId, type, kMetadataBufferTypeGrallocSource);
949 return;
950 }
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -0700951
952 // Release the buffer back to the recording queue
953
954 buffer_handle_t imgHandle = *(buffer_handle_t*)(data + 4);
955
956 size_t itemIndex;
957 for (itemIndex = 0; itemIndex < mRecordingBuffers.size(); itemIndex++) {
958 const BufferItemConsumer::BufferItem item = mRecordingBuffers[itemIndex];
959 if (item.mBuf != BufferItemConsumer::INVALID_BUFFER_SLOT &&
960 item.mGraphicBuffer->handle == imgHandle) {
961 break;
962 }
963 }
964 if (itemIndex == mRecordingBuffers.size()) {
965 ALOGE("%s: Camera %d: Can't find buffer_handle_t %p in list of "
966 "outstanding buffers", __FUNCTION__, mCameraId, imgHandle);
967 return;
968 }
969
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700970 ALOGV("%s: Camera %d: Freeing buffer_handle_t %p", __FUNCTION__, mCameraId,
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -0700971 imgHandle);
972
973 res = mRecordingConsumer->releaseBuffer(mRecordingBuffers[itemIndex]);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700974 if (res != OK) {
975 ALOGE("%s: Camera %d: Unable to free recording frame (buffer_handle_t: %p):"
976 "%s (%d)",
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -0700977 __FUNCTION__, mCameraId, imgHandle, strerror(-res), res);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700978 return;
979 }
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -0700980 mRecordingBuffers.replaceAt(itemIndex);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700981
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700982 mRecordingHeapFree++;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700983}
984
985status_t Camera2Client::autoFocus() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700986 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700987 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700988 status_t res;
989 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
990
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700991 int triggerId;
992 {
993 LockedParameters::Key k(mParameters);
994 k.mParameters.currentAfTriggerId = ++k.mParameters.afTriggerCounter;
995 triggerId = k.mParameters.currentAfTriggerId;
996 }
997
998 mDevice->triggerAutofocus(triggerId);
999
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001000 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001001}
1002
1003status_t Camera2Client::cancelAutoFocus() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001004 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001005 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001006 status_t res;
1007 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
1008
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001009 int triggerId;
1010 {
1011 LockedParameters::Key k(mParameters);
1012 triggerId = ++k.mParameters.afTriggerCounter;
1013 }
1014
1015 mDevice->triggerCancelAutofocus(triggerId);
1016
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001017 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001018}
1019
1020status_t Camera2Client::takePicture(int msgType) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001021 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001022 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001023 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001024 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001025
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001026 LockedParameters::Key k(mParameters);
1027 switch (k.mParameters.state) {
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001028 case DISCONNECTED:
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001029 case STOPPED:
1030 case WAITING_FOR_PREVIEW_WINDOW:
1031 ALOGE("%s: Camera %d: Cannot take picture without preview enabled",
1032 __FUNCTION__, mCameraId);
1033 return INVALID_OPERATION;
1034 case PREVIEW:
1035 case RECORD:
1036 // Good to go for takePicture
1037 break;
1038 case STILL_CAPTURE:
1039 case VIDEO_SNAPSHOT:
1040 ALOGE("%s: Camera %d: Already taking a picture",
1041 __FUNCTION__, mCameraId);
1042 return INVALID_OPERATION;
1043 }
1044
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001045 ALOGV("%s: Camera %d: Starting picture capture", __FUNCTION__, mCameraId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001046
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001047 res = updateCaptureStream(k.mParameters);
1048 if (res != OK) {
1049 ALOGE("%s: Camera %d: Can't set up still image stream: %s (%d)",
1050 __FUNCTION__, mCameraId, strerror(-res), res);
1051 return res;
1052 }
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001053
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001054 if (mCaptureRequest.entryCount() == 0) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001055 res = updateCaptureRequest(k.mParameters);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -07001056 if (res != OK) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001057 ALOGE("%s: Camera %d: Can't create still image capture request: "
1058 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -07001059 return res;
1060 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001061 }
1062
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001063 bool callbacksEnabled = k.mParameters.previewCallbackFlags &
1064 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK;
1065 bool recordingEnabled = (k.mParameters.state == RECORD);
1066
1067 int streamSwitch = (callbacksEnabled ? 0x2 : 0x0) +
1068 (recordingEnabled ? 0x1 : 0x0);
1069 switch ( streamSwitch ) {
1070 case 0: { // No recording, callbacks
1071 uint8_t streamIds[2] = { mPreviewStreamId, mCaptureStreamId };
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001072 res = mCaptureRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS,
1073 streamIds, 2);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001074 break;
1075 }
1076 case 1: { // Recording
1077 uint8_t streamIds[3] = { mPreviewStreamId, mRecordingStreamId,
1078 mCaptureStreamId };
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001079 res = mCaptureRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS,
1080 streamIds, 3);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001081 break;
1082 }
1083 case 2: { // Callbacks
1084 uint8_t streamIds[3] = { mPreviewStreamId, mCallbackStreamId,
1085 mCaptureStreamId };
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001086 res = mCaptureRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS,
1087 streamIds, 3);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001088 break;
1089 }
1090 case 3: { // Both
1091 uint8_t streamIds[4] = { mPreviewStreamId, mCallbackStreamId,
1092 mRecordingStreamId, mCaptureStreamId };
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001093 res = mCaptureRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS,
1094 streamIds, 4);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001095 break;
1096 }
1097 };
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001098 if (res != OK) {
1099 ALOGE("%s: Camera %d: Unable to set up still image capture request: "
1100 "%s (%d)",
1101 __FUNCTION__, mCameraId, strerror(-res), res);
1102 return res;
1103 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001104 res = mCaptureRequest.sort();
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001105 if (res != OK) {
1106 ALOGE("%s: Camera %d: Unable to sort capture request: %s (%d)",
1107 __FUNCTION__, mCameraId, strerror(-res), res);
1108 return res;
1109 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001110
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001111 CameraMetadata captureCopy = mCaptureRequest;
1112 if (captureCopy.entryCount() == 0) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001113 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device",
1114 __FUNCTION__, mCameraId);
1115 return NO_MEMORY;
1116 }
1117
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001118 if (k.mParameters.state == PREVIEW) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001119 res = mDevice->clearStreamingRequest();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001120 if (res != OK) {
1121 ALOGE("%s: Camera %d: Unable to stop preview for still capture: "
1122 "%s (%d)",
1123 __FUNCTION__, mCameraId, strerror(-res), res);
1124 return res;
1125 }
1126 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001127 // TODO: Capture should be atomic with setStreamingRequest here
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001128 res = mDevice->capture(captureCopy);
1129 if (res != OK) {
1130 ALOGE("%s: Camera %d: Unable to submit still image capture request: "
1131 "%s (%d)",
1132 __FUNCTION__, mCameraId, strerror(-res), res);
1133 return res;
1134 }
1135
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001136 switch (k.mParameters.state) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001137 case PREVIEW:
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001138 k.mParameters.state = STILL_CAPTURE;
1139 res = commandStopFaceDetectionL(k.mParameters);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001140 if (res != OK) {
1141 ALOGE("%s: Camera %d: Unable to stop face detection for still capture",
1142 __FUNCTION__, mCameraId);
1143 return res;
1144 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001145 break;
1146 case RECORD:
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001147 k.mParameters.state = VIDEO_SNAPSHOT;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001148 break;
1149 default:
1150 ALOGE("%s: Camera %d: Unknown state for still capture!",
1151 __FUNCTION__, mCameraId);
1152 return INVALID_OPERATION;
1153 }
1154
1155 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001156}
1157
1158status_t Camera2Client::setParameters(const String8& params) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001159 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -07001160 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001161 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001162 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001163 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
1164
1165 LockedParameters::Key k(mParameters);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001166
1167 CameraParameters newParams(params);
1168
1169 // TODO: Currently ignoring any changes to supposedly read-only
1170 // parameters such as supported preview sizes, etc. Should probably
1171 // produce an error if they're changed.
1172
1173 /** Extract and verify new parameters */
1174
1175 size_t i;
1176
1177 // PREVIEW_SIZE
1178 int previewWidth, previewHeight;
1179 newParams.getPreviewSize(&previewWidth, &previewHeight);
1180
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001181 if (previewWidth != k.mParameters.previewWidth ||
1182 previewHeight != k.mParameters.previewHeight) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001183 if (k.mParameters.state >= PREVIEW) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001184 ALOGE("%s: Preview size cannot be updated when preview "
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001185 "is active! (Currently %d x %d, requested %d x %d",
1186 __FUNCTION__,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001187 k.mParameters.previewWidth, k.mParameters.previewHeight,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001188 previewWidth, previewHeight);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001189 return BAD_VALUE;
1190 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001191 camera_metadata_ro_entry_t availablePreviewSizes =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001192 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
1193 for (i = 0; i < availablePreviewSizes.count; i += 2 ) {
1194 if (availablePreviewSizes.data.i32[i] == previewWidth &&
1195 availablePreviewSizes.data.i32[i+1] == previewHeight) break;
1196 }
1197 if (i == availablePreviewSizes.count) {
1198 ALOGE("%s: Requested preview size %d x %d is not supported",
1199 __FUNCTION__, previewWidth, previewHeight);
1200 return BAD_VALUE;
1201 }
1202 }
1203
1204 // PREVIEW_FPS_RANGE
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001205 int previewFpsRange[2];
1206 int previewFps = 0;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001207 bool fpsRangeChanged = false;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001208 newParams.getPreviewFpsRange(&previewFpsRange[0], &previewFpsRange[1]);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001209 if (previewFpsRange[0] != k.mParameters.previewFpsRange[0] ||
1210 previewFpsRange[1] != k.mParameters.previewFpsRange[1]) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001211 fpsRangeChanged = true;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001212 camera_metadata_ro_entry_t availablePreviewFpsRanges =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001213 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
1214 for (i = 0; i < availablePreviewFpsRanges.count; i += 2) {
1215 if ((availablePreviewFpsRanges.data.i32[i] ==
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001216 previewFpsRange[0]) &&
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001217 (availablePreviewFpsRanges.data.i32[i+1] ==
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001218 previewFpsRange[1]) ) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001219 break;
1220 }
1221 }
1222 if (i == availablePreviewFpsRanges.count) {
1223 ALOGE("%s: Requested preview FPS range %d - %d is not supported",
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001224 __FUNCTION__, previewFpsRange[0], previewFpsRange[1]);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001225 return BAD_VALUE;
1226 }
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001227 previewFps = previewFpsRange[0];
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001228 }
1229
1230 // PREVIEW_FORMAT
1231 int previewFormat = formatStringToEnum(newParams.getPreviewFormat());
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001232 if (previewFormat != k.mParameters.previewFormat) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001233 if (k.mParameters.state >= PREVIEW) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001234 ALOGE("%s: Preview format cannot be updated when preview "
1235 "is active!", __FUNCTION__);
1236 return BAD_VALUE;
1237 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001238 camera_metadata_ro_entry_t availableFormats =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001239 staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
1240 for (i = 0; i < availableFormats.count; i++) {
1241 if (availableFormats.data.i32[i] == previewFormat) break;
1242 }
1243 if (i == availableFormats.count) {
1244 ALOGE("%s: Requested preview format %s (0x%x) is not supported",
1245 __FUNCTION__, newParams.getPreviewFormat(), previewFormat);
1246 return BAD_VALUE;
1247 }
1248 }
1249
1250 // PREVIEW_FRAME_RATE
1251 // Deprecated, only use if the preview fps range is unchanged this time.
1252 // The single-value FPS is the same as the minimum of the range.
1253 if (!fpsRangeChanged) {
1254 previewFps = newParams.getPreviewFrameRate();
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001255 if (previewFps != k.mParameters.previewFps) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001256 camera_metadata_ro_entry_t availableFrameRates =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001257 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
1258 for (i = 0; i < availableFrameRates.count; i+=2) {
1259 if (availableFrameRates.data.i32[i] == previewFps) break;
1260 }
1261 if (i == availableFrameRates.count) {
1262 ALOGE("%s: Requested preview frame rate %d is not supported",
1263 __FUNCTION__, previewFps);
1264 return BAD_VALUE;
1265 }
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001266 previewFpsRange[0] = availableFrameRates.data.i32[i];
1267 previewFpsRange[1] = availableFrameRates.data.i32[i+1];
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001268 }
1269 }
1270
1271 // PICTURE_SIZE
1272 int pictureWidth, pictureHeight;
1273 newParams.getPictureSize(&pictureWidth, &pictureHeight);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001274 if (pictureWidth == k.mParameters.pictureWidth ||
1275 pictureHeight == k.mParameters.pictureHeight) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001276 camera_metadata_ro_entry_t availablePictureSizes =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001277 staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES);
1278 for (i = 0; i < availablePictureSizes.count; i+=2) {
1279 if (availablePictureSizes.data.i32[i] == pictureWidth &&
1280 availablePictureSizes.data.i32[i+1] == pictureHeight) break;
1281 }
1282 if (i == availablePictureSizes.count) {
1283 ALOGE("%s: Requested picture size %d x %d is not supported",
1284 __FUNCTION__, pictureWidth, pictureHeight);
1285 return BAD_VALUE;
1286 }
1287 }
1288
1289 // JPEG_THUMBNAIL_WIDTH/HEIGHT
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001290 int jpegThumbSize[2];
1291 jpegThumbSize[0] =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001292 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001293 jpegThumbSize[1] =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001294 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001295 if (jpegThumbSize[0] != k.mParameters.jpegThumbSize[0] ||
1296 jpegThumbSize[1] != k.mParameters.jpegThumbSize[1]) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001297 camera_metadata_ro_entry_t availableJpegThumbSizes =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001298 staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES);
1299 for (i = 0; i < availableJpegThumbSizes.count; i+=2) {
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001300 if (availableJpegThumbSizes.data.i32[i] == jpegThumbSize[0] &&
1301 availableJpegThumbSizes.data.i32[i+1] == jpegThumbSize[1]) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001302 break;
1303 }
1304 }
1305 if (i == availableJpegThumbSizes.count) {
1306 ALOGE("%s: Requested JPEG thumbnail size %d x %d is not supported",
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001307 __FUNCTION__, jpegThumbSize[0], jpegThumbSize[1]);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001308 return BAD_VALUE;
1309 }
1310 }
1311
1312 // JPEG_THUMBNAIL_QUALITY
1313 int jpegThumbQuality =
1314 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
1315 if (jpegThumbQuality < 0 || jpegThumbQuality > 100) {
1316 ALOGE("%s: Requested JPEG thumbnail quality %d is not supported",
1317 __FUNCTION__, jpegThumbQuality);
1318 return BAD_VALUE;
1319 }
1320
1321 // JPEG_QUALITY
1322 int jpegQuality =
1323 newParams.getInt(CameraParameters::KEY_JPEG_QUALITY);
1324 if (jpegQuality < 0 || jpegQuality > 100) {
1325 ALOGE("%s: Requested JPEG quality %d is not supported",
1326 __FUNCTION__, jpegQuality);
1327 return BAD_VALUE;
1328 }
1329
1330 // ROTATION
1331 int jpegRotation =
1332 newParams.getInt(CameraParameters::KEY_ROTATION);
1333 if (jpegRotation != 0 &&
1334 jpegRotation != 90 &&
1335 jpegRotation != 180 &&
1336 jpegRotation != 270) {
1337 ALOGE("%s: Requested picture rotation angle %d is not supported",
1338 __FUNCTION__, jpegRotation);
1339 return BAD_VALUE;
1340 }
1341
1342 // GPS
1343 bool gpsEnabled = false;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001344 double gpsCoordinates[3] = {0,0,0};
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001345 int64_t gpsTimestamp = 0;
1346 String8 gpsProcessingMethod;
1347 const char *gpsLatStr =
1348 newParams.get(CameraParameters::KEY_GPS_LATITUDE);
1349 if (gpsLatStr != NULL) {
1350 const char *gpsLongStr =
1351 newParams.get(CameraParameters::KEY_GPS_LONGITUDE);
1352 const char *gpsAltitudeStr =
1353 newParams.get(CameraParameters::KEY_GPS_ALTITUDE);
1354 const char *gpsTimeStr =
1355 newParams.get(CameraParameters::KEY_GPS_TIMESTAMP);
1356 const char *gpsProcMethodStr =
1357 newParams.get(CameraParameters::KEY_GPS_PROCESSING_METHOD);
1358 if (gpsLongStr == NULL ||
1359 gpsAltitudeStr == NULL ||
1360 gpsTimeStr == NULL ||
1361 gpsProcMethodStr == NULL) {
1362 ALOGE("%s: Incomplete set of GPS parameters provided",
1363 __FUNCTION__);
1364 return BAD_VALUE;
1365 }
1366 char *endPtr;
1367 errno = 0;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001368 gpsCoordinates[0] = strtod(gpsLatStr, &endPtr);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001369 if (errno || endPtr == gpsLatStr) {
1370 ALOGE("%s: Malformed GPS latitude: %s", __FUNCTION__, gpsLatStr);
1371 return BAD_VALUE;
1372 }
1373 errno = 0;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001374 gpsCoordinates[1] = strtod(gpsLongStr, &endPtr);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001375 if (errno || endPtr == gpsLongStr) {
1376 ALOGE("%s: Malformed GPS longitude: %s", __FUNCTION__, gpsLongStr);
1377 return BAD_VALUE;
1378 }
1379 errno = 0;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001380 gpsCoordinates[2] = strtod(gpsAltitudeStr, &endPtr);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001381 if (errno || endPtr == gpsAltitudeStr) {
1382 ALOGE("%s: Malformed GPS altitude: %s", __FUNCTION__,
1383 gpsAltitudeStr);
1384 return BAD_VALUE;
1385 }
1386 errno = 0;
1387 gpsTimestamp = strtoll(gpsTimeStr, &endPtr, 10);
1388 if (errno || endPtr == gpsTimeStr) {
1389 ALOGE("%s: Malformed GPS timestamp: %s", __FUNCTION__, gpsTimeStr);
1390 return BAD_VALUE;
1391 }
1392 gpsProcessingMethod = gpsProcMethodStr;
1393
1394 gpsEnabled = true;
1395 }
1396
1397 // WHITE_BALANCE
1398 int wbMode = wbModeStringToEnum(
1399 newParams.get(CameraParameters::KEY_WHITE_BALANCE) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001400 if (wbMode != k.mParameters.wbMode) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001401 camera_metadata_ro_entry_t availableWbModes =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001402 staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
1403 for (i = 0; i < availableWbModes.count; i++) {
1404 if (wbMode == availableWbModes.data.u8[i]) break;
1405 }
1406 if (i == availableWbModes.count) {
1407 ALOGE("%s: Requested white balance mode %s is not supported",
1408 __FUNCTION__,
1409 newParams.get(CameraParameters::KEY_WHITE_BALANCE));
1410 return BAD_VALUE;
1411 }
1412 }
1413
1414 // EFFECT
1415 int effectMode = effectModeStringToEnum(
1416 newParams.get(CameraParameters::KEY_EFFECT) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001417 if (effectMode != k.mParameters.effectMode) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001418 camera_metadata_ro_entry_t availableEffectModes =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001419 staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
1420 for (i = 0; i < availableEffectModes.count; i++) {
1421 if (effectMode == availableEffectModes.data.u8[i]) break;
1422 }
1423 if (i == availableEffectModes.count) {
1424 ALOGE("%s: Requested effect mode \"%s\" is not supported",
1425 __FUNCTION__,
1426 newParams.get(CameraParameters::KEY_EFFECT) );
1427 return BAD_VALUE;
1428 }
1429 }
1430
1431 // ANTIBANDING
1432 int antibandingMode = abModeStringToEnum(
1433 newParams.get(CameraParameters::KEY_ANTIBANDING) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001434 if (antibandingMode != k.mParameters.antibandingMode) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001435 camera_metadata_ro_entry_t availableAbModes =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001436 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
1437 for (i = 0; i < availableAbModes.count; i++) {
1438 if (antibandingMode == availableAbModes.data.u8[i]) break;
1439 }
1440 if (i == availableAbModes.count) {
1441 ALOGE("%s: Requested antibanding mode \"%s\" is not supported",
1442 __FUNCTION__,
1443 newParams.get(CameraParameters::KEY_ANTIBANDING));
1444 return BAD_VALUE;
1445 }
1446 }
1447
1448 // SCENE_MODE
1449 int sceneMode = sceneModeStringToEnum(
1450 newParams.get(CameraParameters::KEY_SCENE_MODE) );
Eino-Ville Talvala3cc89792012-08-16 16:03:59 -07001451 if (sceneMode != k.mParameters.sceneMode &&
1452 sceneMode != ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001453 camera_metadata_ro_entry_t availableSceneModes =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001454 staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
1455 for (i = 0; i < availableSceneModes.count; i++) {
1456 if (sceneMode == availableSceneModes.data.u8[i]) break;
1457 }
1458 if (i == availableSceneModes.count) {
1459 ALOGE("%s: Requested scene mode \"%s\" is not supported",
1460 __FUNCTION__,
1461 newParams.get(CameraParameters::KEY_SCENE_MODE));
1462 return BAD_VALUE;
1463 }
1464 }
1465
1466 // FLASH_MODE
1467 Parameters::flashMode_t flashMode = flashModeStringToEnum(
1468 newParams.get(CameraParameters::KEY_FLASH_MODE) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001469 if (flashMode != k.mParameters.flashMode) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001470 camera_metadata_ro_entry_t flashAvailable =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001471 staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
1472 if (!flashAvailable.data.u8[0] &&
1473 flashMode != Parameters::FLASH_MODE_OFF) {
1474 ALOGE("%s: Requested flash mode \"%s\" is not supported: "
1475 "No flash on device", __FUNCTION__,
1476 newParams.get(CameraParameters::KEY_FLASH_MODE));
1477 return BAD_VALUE;
1478 } else if (flashMode == Parameters::FLASH_MODE_RED_EYE) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001479 camera_metadata_ro_entry_t availableAeModes =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001480 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
1481 for (i = 0; i < availableAeModes.count; i++) {
1482 if (flashMode == availableAeModes.data.u8[i]) break;
1483 }
1484 if (i == availableAeModes.count) {
1485 ALOGE("%s: Requested flash mode \"%s\" is not supported",
1486 __FUNCTION__,
1487 newParams.get(CameraParameters::KEY_FLASH_MODE));
1488 return BAD_VALUE;
1489 }
1490 } else if (flashMode == -1) {
1491 ALOGE("%s: Requested flash mode \"%s\" is unknown",
1492 __FUNCTION__,
1493 newParams.get(CameraParameters::KEY_FLASH_MODE));
1494 return BAD_VALUE;
1495 }
1496 }
1497
1498 // FOCUS_MODE
1499 Parameters::focusMode_t focusMode = focusModeStringToEnum(
1500 newParams.get(CameraParameters::KEY_FOCUS_MODE));
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001501 if (focusMode != k.mParameters.focusMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001502 if (focusMode != Parameters::FOCUS_MODE_FIXED) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001503 camera_metadata_ro_entry_t minFocusDistance =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001504 staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE);
1505 if (minFocusDistance.data.f[0] == 0) {
1506 ALOGE("%s: Requested focus mode \"%s\" is not available: "
1507 "fixed focus lens",
1508 __FUNCTION__,
1509 newParams.get(CameraParameters::KEY_FOCUS_MODE));
1510 return BAD_VALUE;
1511 } else if (focusMode != Parameters::FOCUS_MODE_INFINITY) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001512 camera_metadata_ro_entry_t availableFocusModes =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001513 staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
1514 for (i = 0; i < availableFocusModes.count; i++) {
1515 if (focusMode == availableFocusModes.data.u8[i]) break;
1516 }
1517 if (i == availableFocusModes.count) {
1518 ALOGE("%s: Requested focus mode \"%s\" is not supported",
1519 __FUNCTION__,
1520 newParams.get(CameraParameters::KEY_FOCUS_MODE));
1521 return BAD_VALUE;
1522 }
1523 }
1524 }
1525 }
1526
1527 // FOCUS_AREAS
1528 Vector<Parameters::Area> focusingAreas;
1529 res = parseAreas(newParams.get(CameraParameters::KEY_FOCUS_AREAS),
1530 &focusingAreas);
1531 size_t max3aRegions =
1532 (size_t)staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1).data.i32[0];
1533 if (res == OK) res = validateAreas(focusingAreas, max3aRegions);
1534 if (res != OK) {
1535 ALOGE("%s: Requested focus areas are malformed: %s",
1536 __FUNCTION__, newParams.get(CameraParameters::KEY_FOCUS_AREAS));
1537 return BAD_VALUE;
1538 }
1539
1540 // EXPOSURE_COMPENSATION
1541 int exposureCompensation =
1542 newParams.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001543 camera_metadata_ro_entry_t exposureCompensationRange =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001544 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE);
1545 if (exposureCompensation < exposureCompensationRange.data.i32[0] ||
1546 exposureCompensation > exposureCompensationRange.data.i32[1]) {
1547 ALOGE("%s: Requested exposure compensation index is out of bounds: %d",
1548 __FUNCTION__, exposureCompensation);
1549 return BAD_VALUE;
1550 }
1551
1552 // AUTO_EXPOSURE_LOCK (always supported)
1553 bool autoExposureLock = boolFromString(
1554 newParams.get(CameraParameters::KEY_AUTO_EXPOSURE_LOCK));
1555
1556 // AUTO_WHITEBALANCE_LOCK (always supported)
1557 bool autoWhiteBalanceLock = boolFromString(
1558 newParams.get(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK));
1559
1560 // METERING_AREAS
1561 Vector<Parameters::Area> meteringAreas;
1562 res = parseAreas(newParams.get(CameraParameters::KEY_METERING_AREAS),
1563 &meteringAreas);
1564 if (res == OK) res = validateAreas(focusingAreas, max3aRegions);
1565 if (res != OK) {
1566 ALOGE("%s: Requested metering areas are malformed: %s",
1567 __FUNCTION__,
1568 newParams.get(CameraParameters::KEY_METERING_AREAS));
1569 return BAD_VALUE;
1570 }
1571
1572 // ZOOM
1573 int zoom = newParams.getInt(CameraParameters::KEY_ZOOM);
1574 if (zoom < 0 || zoom > (int)NUM_ZOOM_STEPS) {
1575 ALOGE("%s: Requested zoom level %d is not supported",
1576 __FUNCTION__, zoom);
1577 return BAD_VALUE;
1578 }
1579
1580 // VIDEO_SIZE
1581 int videoWidth, videoHeight;
1582 newParams.getVideoSize(&videoWidth, &videoHeight);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001583 if (videoWidth != k.mParameters.videoWidth ||
1584 videoHeight != k.mParameters.videoHeight) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001585 if (k.mParameters.state == RECORD) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001586 ALOGE("%s: Video size cannot be updated when recording is active!",
1587 __FUNCTION__);
1588 return BAD_VALUE;
1589 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001590 camera_metadata_ro_entry_t availableVideoSizes =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001591 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
1592 for (i = 0; i < availableVideoSizes.count; i += 2 ) {
1593 if (availableVideoSizes.data.i32[i] == videoWidth &&
1594 availableVideoSizes.data.i32[i+1] == videoHeight) break;
1595 }
1596 if (i == availableVideoSizes.count) {
1597 ALOGE("%s: Requested video size %d x %d is not supported",
1598 __FUNCTION__, videoWidth, videoHeight);
1599 return BAD_VALUE;
1600 }
1601 }
1602
1603 // RECORDING_HINT (always supported)
1604 bool recordingHint = boolFromString(
1605 newParams.get(CameraParameters::KEY_RECORDING_HINT) );
1606
1607 // VIDEO_STABILIZATION
1608 bool videoStabilization = boolFromString(
1609 newParams.get(CameraParameters::KEY_VIDEO_STABILIZATION) );
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001610 camera_metadata_ro_entry_t availableVideoStabilizationModes =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001611 staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
1612 if (videoStabilization && availableVideoStabilizationModes.count == 1) {
1613 ALOGE("%s: Video stabilization not supported", __FUNCTION__);
1614 }
1615
1616 /** Update internal parameters */
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001617
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001618 k.mParameters.previewWidth = previewWidth;
1619 k.mParameters.previewHeight = previewHeight;
1620 k.mParameters.previewFpsRange[0] = previewFpsRange[0];
1621 k.mParameters.previewFpsRange[1] = previewFpsRange[1];
1622 k.mParameters.previewFps = previewFps;
1623 k.mParameters.previewFormat = previewFormat;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001624
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001625 k.mParameters.pictureWidth = pictureWidth;
1626 k.mParameters.pictureHeight = pictureHeight;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001627
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001628 k.mParameters.jpegThumbSize[0] = jpegThumbSize[0];
1629 k.mParameters.jpegThumbSize[1] = jpegThumbSize[1];
1630 k.mParameters.jpegQuality = jpegQuality;
1631 k.mParameters.jpegThumbQuality = jpegThumbQuality;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001632
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001633 k.mParameters.gpsEnabled = gpsEnabled;
1634 k.mParameters.gpsCoordinates[0] = gpsCoordinates[0];
1635 k.mParameters.gpsCoordinates[1] = gpsCoordinates[1];
1636 k.mParameters.gpsCoordinates[2] = gpsCoordinates[2];
1637 k.mParameters.gpsTimestamp = gpsTimestamp;
1638 k.mParameters.gpsProcessingMethod = gpsProcessingMethod;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001639
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001640 k.mParameters.wbMode = wbMode;
1641 k.mParameters.effectMode = effectMode;
1642 k.mParameters.antibandingMode = antibandingMode;
1643 k.mParameters.sceneMode = sceneMode;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001644
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001645 k.mParameters.flashMode = flashMode;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001646 if (focusMode != k.mParameters.focusMode) {
1647 k.mParameters.currentAfTriggerId = -1;
1648 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001649 k.mParameters.focusMode = focusMode;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001650
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001651 k.mParameters.focusingAreas = focusingAreas;
1652 k.mParameters.exposureCompensation = exposureCompensation;
1653 k.mParameters.autoExposureLock = autoExposureLock;
1654 k.mParameters.autoWhiteBalanceLock = autoWhiteBalanceLock;
1655 k.mParameters.meteringAreas = meteringAreas;
1656 k.mParameters.zoom = zoom;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001657
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001658 k.mParameters.videoWidth = videoWidth;
1659 k.mParameters.videoHeight = videoHeight;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001660
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001661 k.mParameters.recordingHint = recordingHint;
1662 k.mParameters.videoStabilization = videoStabilization;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001663
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001664 k.mParameters.paramsFlattened = params;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001665
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001666 res = updateRequests(k.mParameters);
1667
1668 return res;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001669}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001670
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001671String8 Camera2Client::getParameters() const {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001672 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001673 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001674 if ( checkPid(__FUNCTION__) != OK) return String8();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001675
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001676 LockedParameters::ReadKey k(mParameters);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001677
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001678 // TODO: Deal with focus distances
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001679 return k.mParameters.paramsFlattened;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001680}
1681
1682status_t Camera2Client::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001683 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001684 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001685 status_t res;
1686 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001687
1688 ALOGV("%s: Camera %d: Command %d (%d, %d)", __FUNCTION__, mCameraId,
1689 cmd, arg1, arg2);
1690
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001691 switch (cmd) {
1692 case CAMERA_CMD_START_SMOOTH_ZOOM:
1693 return commandStartSmoothZoomL();
1694 case CAMERA_CMD_STOP_SMOOTH_ZOOM:
1695 return commandStopSmoothZoomL();
1696 case CAMERA_CMD_SET_DISPLAY_ORIENTATION:
1697 return commandSetDisplayOrientationL(arg1);
1698 case CAMERA_CMD_ENABLE_SHUTTER_SOUND:
1699 return commandEnableShutterSoundL(arg1 == 1);
1700 case CAMERA_CMD_PLAY_RECORDING_SOUND:
1701 return commandPlayRecordingSoundL();
1702 case CAMERA_CMD_START_FACE_DETECTION:
1703 return commandStartFaceDetectionL(arg1);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001704 case CAMERA_CMD_STOP_FACE_DETECTION: {
1705 LockedParameters::Key k(mParameters);
1706 return commandStopFaceDetectionL(k.mParameters);
1707 }
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001708 case CAMERA_CMD_ENABLE_FOCUS_MOVE_MSG:
1709 return commandEnableFocusMoveMsgL(arg1 == 1);
1710 case CAMERA_CMD_PING:
1711 return commandPingL();
1712 case CAMERA_CMD_SET_VIDEO_BUFFER_COUNT:
1713 return commandSetVideoBufferCountL(arg1);
1714 default:
1715 ALOGE("%s: Unknown command %d (arguments %d, %d)",
1716 __FUNCTION__, cmd, arg1, arg2);
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001717 return BAD_VALUE;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001718 }
1719}
James Dong983cf232012-08-01 16:39:55 -07001720
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001721status_t Camera2Client::commandStartSmoothZoomL() {
1722 ALOGE("%s: Unimplemented!", __FUNCTION__);
1723 return OK;
1724}
James Dong983cf232012-08-01 16:39:55 -07001725
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001726status_t Camera2Client::commandStopSmoothZoomL() {
1727 ALOGE("%s: Unimplemented!", __FUNCTION__);
1728 return OK;
1729}
James Dong983cf232012-08-01 16:39:55 -07001730
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001731status_t Camera2Client::commandSetDisplayOrientationL(int degrees) {
1732 LockedParameters::Key k(mParameters);
1733 int transform = degToTransform(degrees,
1734 mCameraFacing == CAMERA_FACING_FRONT);
1735 if (transform == -1) {
1736 ALOGE("%s: Camera %d: Error setting %d as display orientation value",
1737 __FUNCTION__, mCameraId, degrees);
1738 return BAD_VALUE;
1739 }
1740 if (transform != k.mParameters.previewTransform &&
1741 mPreviewStreamId != NO_STREAM) {
1742 mDevice->setStreamTransform(mPreviewStreamId, transform);
1743 }
1744 k.mParameters.previewTransform = transform;
1745 return OK;
1746}
1747
1748status_t Camera2Client::commandEnableShutterSoundL(bool enable) {
1749 LockedParameters::Key k(mParameters);
1750 if (enable) {
1751 k.mParameters.playShutterSound = true;
James Dong983cf232012-08-01 16:39:55 -07001752 return OK;
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001753 }
1754
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001755 // Disabling shutter sound may not be allowed. In that case only
1756 // allow the mediaserver process to disable the sound.
1757 char value[PROPERTY_VALUE_MAX];
1758 property_get("ro.camera.sound.forced", value, "0");
1759 if (strncmp(value, "0", 2) != 0) {
1760 // Disabling shutter sound is not allowed. Deny if the current
1761 // process is not mediaserver.
1762 if (getCallingPid() != getpid()) {
1763 ALOGE("Failed to disable shutter sound. Permission denied (pid %d)",
1764 getCallingPid());
1765 return PERMISSION_DENIED;
1766 }
1767 }
1768
1769 k.mParameters.playShutterSound = false;
1770 return OK;
1771}
1772
1773status_t Camera2Client::commandPlayRecordingSoundL() {
1774 mCameraService->playSound(CameraService::SOUND_RECORDING);
1775 return OK;
1776}
1777
1778status_t Camera2Client::commandStartFaceDetectionL(int type) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001779 ALOGV("%s: Camera %d: Starting face detection",
1780 __FUNCTION__, mCameraId);
1781 status_t res;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001782 LockedParameters::Key k(mParameters);
1783 switch (k.mParameters.state) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001784 case DISCONNECTED:
1785 case STOPPED:
1786 case WAITING_FOR_PREVIEW_WINDOW:
1787 case STILL_CAPTURE:
1788 ALOGE("%s: Camera %d: Cannot start face detection without preview active",
1789 __FUNCTION__, mCameraId);
1790 return INVALID_OPERATION;
1791 case PREVIEW:
1792 case RECORD:
1793 case VIDEO_SNAPSHOT:
1794 // Good to go for starting face detect
1795 break;
1796 }
1797 // Ignoring type
1798 if (mDeviceInfo->bestFaceDetectMode == ANDROID_STATS_FACE_DETECTION_OFF) {
1799 ALOGE("%s: Camera %d: Face detection not supported",
1800 __FUNCTION__, mCameraId);
1801 return INVALID_OPERATION;
1802 }
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001803 if (k.mParameters.enableFaceDetect) return OK;
1804
1805 k.mParameters.enableFaceDetect = true;
1806
1807 res = updateRequests(k.mParameters);
1808
1809 return res;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001810}
1811
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001812status_t Camera2Client::commandStopFaceDetectionL(Parameters &params) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001813 status_t res = OK;
1814 ALOGV("%s: Camera %d: Stopping face detection",
1815 __FUNCTION__, mCameraId);
1816
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001817 if (!params.enableFaceDetect) return OK;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001818
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001819 params.enableFaceDetect = false;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001820
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001821 if (params.state == PREVIEW || params.state == RECORD ||
1822 params.state == VIDEO_SNAPSHOT) {
1823 res = updateRequests(params);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001824 }
1825
1826 return res;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001827}
1828
1829status_t Camera2Client::commandEnableFocusMoveMsgL(bool enable) {
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001830 LockedParameters::Key k(mParameters);
1831 k.mParameters.enableFocusMoveMessages = enable;
1832
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001833 return OK;
1834}
1835
1836status_t Camera2Client::commandPingL() {
1837 // Always ping back if access is proper and device is alive
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001838 LockedParameters::Key k(mParameters);
1839 if (k.mParameters.state != DISCONNECTED) {
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001840 return OK;
1841 } else {
1842 return NO_INIT;
1843 }
1844}
1845
1846status_t Camera2Client::commandSetVideoBufferCountL(size_t count) {
James Dong8da4cd72012-08-04 19:58:07 -07001847 if (recordingEnabledL()) {
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001848 ALOGE("%s: Camera %d: Error setting video buffer count after "
1849 "recording was started", __FUNCTION__, mCameraId);
1850 return INVALID_OPERATION;
1851 }
1852
1853 // 32 is the current upper limit on the video buffer count for BufferQueue
1854 if (count > 32) {
1855 ALOGE("%s: Camera %d: Error setting %d as video buffer count value",
1856 __FUNCTION__, mCameraId, count);
1857 return BAD_VALUE;
1858 }
1859
1860 // Need to reallocate memory for heap
1861 if (mRecordingHeapCount != count) {
1862 if (mRecordingHeap != 0) {
1863 mRecordingHeap.clear();
1864 mRecordingHeap = NULL;
1865 }
1866 mRecordingHeapCount = count;
1867 }
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001868
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001869 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001870}
1871
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001872/** Device-related methods */
1873
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -07001874void Camera2Client::notifyError(int errorCode, int arg1, int arg2) {
1875 ALOGE("Error condition %d reported by HAL, arguments %d, %d", errorCode, arg1, arg2);
1876}
1877
1878void Camera2Client::notifyShutter(int frameNumber, nsecs_t timestamp) {
1879 ALOGV("%s: Shutter notification for frame %d at time %lld", __FUNCTION__,
1880 frameNumber, timestamp);
1881}
1882
1883void Camera2Client::notifyAutoFocus(uint8_t newState, int triggerId) {
1884 ALOGV("%s: Autofocus state now %d, last trigger %d",
1885 __FUNCTION__, newState, triggerId);
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001886 bool sendCompletedMessage = false;
1887 bool sendMovingMessage = false;
1888
1889 bool success = false;
1890 bool afInMotion = false;
1891 {
1892 LockedParameters::Key k(mParameters);
1893 switch (k.mParameters.focusMode) {
1894 case Parameters::FOCUS_MODE_AUTO:
1895 case Parameters::FOCUS_MODE_MACRO:
1896 // Don't send notifications upstream if they're not for the current AF
1897 // trigger. For example, if cancel was called in between, or if we
1898 // already sent a notification about this AF call.
1899 if (triggerId != k.mParameters.currentAfTriggerId) break;
1900 switch (newState) {
1901 case ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED:
1902 success = true;
1903 // no break
1904 case ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
1905 sendCompletedMessage = true;
1906 k.mParameters.currentAfTriggerId = -1;
1907 break;
1908 case ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN:
1909 // Just starting focusing, ignore
1910 break;
1911 case ANDROID_CONTROL_AF_STATE_INACTIVE:
1912 case ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN:
1913 case ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED:
1914 default:
1915 // Unexpected in AUTO/MACRO mode
1916 ALOGE("%s: Unexpected AF state transition in AUTO/MACRO mode: %d",
1917 __FUNCTION__, newState);
1918 break;
1919 }
1920 break;
1921 case Parameters::FOCUS_MODE_CONTINUOUS_VIDEO:
1922 case Parameters::FOCUS_MODE_CONTINUOUS_PICTURE:
1923 switch (newState) {
1924 case ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED:
1925 success = true;
1926 // no break
1927 case ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
1928 // Don't send notifications upstream if they're not for
1929 // the current AF trigger. For example, if cancel was
1930 // called in between, or if we already sent a
1931 // notification about this AF call.
1932 // Send both a 'AF done' callback and a 'AF move' callback
1933 if (triggerId != k.mParameters.currentAfTriggerId) break;
1934 sendCompletedMessage = true;
1935 afInMotion = false;
1936 if (k.mParameters.enableFocusMoveMessages &&
1937 k.mParameters.afInMotion) {
1938 sendMovingMessage = true;
1939 }
1940 k.mParameters.currentAfTriggerId = -1;
1941 break;
1942 case ANDROID_CONTROL_AF_STATE_INACTIVE:
1943 // Cancel was called, or we switched state; care if
1944 // currently moving
1945 afInMotion = false;
1946 if (k.mParameters.enableFocusMoveMessages &&
1947 k.mParameters.afInMotion) {
1948 sendMovingMessage = true;
1949 }
1950 break;
1951 case ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN:
1952 // Start passive scan, inform upstream
1953 afInMotion = true;
1954 // no break
1955 case ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED:
1956 // Stop passive scan, inform upstream
1957 if (k.mParameters.enableFocusMoveMessages) {
1958 sendMovingMessage = true;
1959 }
1960 break;
1961 }
1962 k.mParameters.afInMotion = afInMotion;
1963 break;
1964 case Parameters::FOCUS_MODE_EDOF:
1965 case Parameters::FOCUS_MODE_INFINITY:
1966 case Parameters::FOCUS_MODE_FIXED:
1967 default:
1968 if (newState != ANDROID_CONTROL_AF_STATE_INACTIVE) {
1969 ALOGE("%s: Unexpected AF state change %d (ID %d) in focus mode %d",
1970 __FUNCTION__, newState, triggerId, k.mParameters.focusMode);
1971 }
1972 }
1973 }
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001974 if (sendMovingMessage) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001975 Mutex::Autolock iccl(mICameraClientLock);
1976 if (mCameraClient != 0) {
1977 mCameraClient->notifyCallback(CAMERA_MSG_FOCUS_MOVE,
1978 afInMotion ? 1 : 0, 0);
1979 }
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001980 }
Eino-Ville Talvala603b12e2012-08-08 09:25:58 -07001981 if (sendCompletedMessage) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001982 Mutex::Autolock iccl(mICameraClientLock);
1983 if (mCameraClient != 0) {
1984 mCameraClient->notifyCallback(CAMERA_MSG_FOCUS, success ? 1 : 0, 0);
1985 }
Eino-Ville Talvala603b12e2012-08-08 09:25:58 -07001986 }
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -07001987}
1988
1989void Camera2Client::notifyAutoExposure(uint8_t newState, int triggerId) {
1990 ALOGV("%s: Autoexposure state now %d, last trigger %d",
1991 __FUNCTION__, newState, triggerId);
1992}
1993
1994void Camera2Client::notifyAutoWhitebalance(uint8_t newState, int triggerId) {
1995 ALOGV("%s: Auto-whitebalance state now %d, last trigger %d",
1996 __FUNCTION__, newState, triggerId);
1997}
1998
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -07001999Camera2Client::FrameProcessor::FrameProcessor(wp<Camera2Client> client):
2000 Thread(false), mClient(client) {
2001}
2002
2003Camera2Client::FrameProcessor::~FrameProcessor() {
2004 ALOGV("%s: Exit", __FUNCTION__);
2005}
2006
2007void Camera2Client::FrameProcessor::dump(int fd, const Vector<String16>& args) {
2008 String8 result(" Latest received frame:\n");
2009 write(fd, result.string(), result.size());
2010 mLastFrame.dump(fd, 2, 6);
2011}
2012
2013bool Camera2Client::FrameProcessor::threadLoop() {
2014 status_t res;
2015
2016 sp<Camera2Device> device;
2017 {
2018 sp<Camera2Client> client = mClient.promote();
2019 if (client == 0) return false;
2020 device = client->mDevice;
2021 }
2022
2023 res = device->waitForNextFrame(kWaitDuration);
2024 if (res == OK) {
2025 sp<Camera2Client> client = mClient.promote();
2026 if (client == 0) return false;
2027 processNewFrames(client);
2028 } else if (res != TIMED_OUT) {
2029 ALOGE("Camera2Client::FrameProcessor: Error waiting for new "
2030 "frames: %s (%d)", strerror(-res), res);
2031 }
2032
2033 return true;
2034}
2035
2036void Camera2Client::FrameProcessor::processNewFrames(sp<Camera2Client> &client) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002037 status_t res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002038 CameraMetadata frame;
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -07002039 while ( (res = client->mDevice->getNextFrame(&frame)) == OK) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002040 camera_metadata_entry_t entry;
2041 entry = frame.find(ANDROID_REQUEST_FRAME_COUNT);
2042 if (entry.count == 0) {
2043 ALOGE("%s: Camera %d: Error reading frame number: %s (%d)",
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -07002044 __FUNCTION__, client->mCameraId, strerror(-res), res);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002045 break;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002046 }
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002047
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -07002048 res = processFaceDetect(frame, client);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002049 if (res != OK) break;
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -07002050
2051 mLastFrame.acquire(frame);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002052 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002053 if (res != NOT_ENOUGH_DATA) {
2054 ALOGE("%s: Camera %d: Error getting next frame: %s (%d)",
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -07002055 __FUNCTION__, client->mCameraId, strerror(-res), res);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002056 return;
2057 }
2058
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002059 return;
2060}
2061
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -07002062status_t Camera2Client::FrameProcessor::processFaceDetect(
2063 const CameraMetadata &frame, sp<Camera2Client> &client) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002064 status_t res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002065 camera_metadata_ro_entry_t entry;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002066 bool enableFaceDetect;
2067 {
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -07002068 LockedParameters::Key k(client->mParameters);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002069 enableFaceDetect = k.mParameters.enableFaceDetect;
2070 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002071 entry = frame.find(ANDROID_STATS_FACE_DETECT_MODE);
2072
2073 // TODO: This should be an error once implementations are compliant
2074 if (entry.count == 0) {
Eino-Ville Talvala76dc8da2012-08-21 16:09:31 -07002075 return OK;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002076 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002077
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002078 uint8_t faceDetectMode = entry.data.u8[0];
2079
2080 if (enableFaceDetect && faceDetectMode != ANDROID_STATS_FACE_DETECTION_OFF) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002081 entry = frame.find(ANDROID_STATS_FACE_RECTANGLES);
2082 if (entry.count == 0) {
2083 ALOGE("%s: Camera %d: Unable to read face rectangles",
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -07002084 __FUNCTION__, client->mCameraId);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002085 return res;
2086 }
2087 camera_frame_metadata metadata;
2088 metadata.number_of_faces = entry.count / 4;
2089 if (metadata.number_of_faces >
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -07002090 client->mDeviceInfo->maxFaces) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002091 ALOGE("%s: Camera %d: More faces than expected! (Got %d, max %d)",
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -07002092 __FUNCTION__, client->mCameraId,
2093 metadata.number_of_faces, client->mDeviceInfo->maxFaces);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002094 return res;
2095 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002096 const int32_t *faceRects = entry.data.i32;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002097
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002098 entry = frame.find(ANDROID_STATS_FACE_SCORES);
2099 if (entry.count == 0) {
2100 ALOGE("%s: Camera %d: Unable to read face scores",
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -07002101 __FUNCTION__, client->mCameraId);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002102 return res;
2103 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002104 const uint8_t *faceScores = entry.data.u8;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002105
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002106 const int32_t *faceLandmarks = NULL;
2107 const int32_t *faceIds = NULL;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002108
2109 if (faceDetectMode == ANDROID_STATS_FACE_DETECTION_FULL) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002110 entry = frame.find(ANDROID_STATS_FACE_LANDMARKS);
2111 if (entry.count == 0) {
2112 ALOGE("%s: Camera %d: Unable to read face landmarks",
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -07002113 __FUNCTION__, client->mCameraId);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002114 return res;
2115 }
2116 faceLandmarks = entry.data.i32;
2117
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002118 entry = frame.find(ANDROID_STATS_FACE_IDS);
2119
2120 if (entry.count == 0) {
2121 ALOGE("%s: Camera %d: Unable to read face IDs",
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -07002122 __FUNCTION__, client->mCameraId);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002123 return res;
2124 }
2125 faceIds = entry.data.i32;
2126 }
2127
2128 Vector<camera_face_t> faces;
2129 faces.setCapacity(metadata.number_of_faces);
2130
2131 for (int i = 0; i < metadata.number_of_faces; i++) {
2132 camera_face_t face;
2133
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -07002134 face.rect[0] = client->arrayXToNormalized(faceRects[i*4 + 0]);
2135 face.rect[1] = client->arrayYToNormalized(faceRects[i*4 + 1]);
2136 face.rect[2] = client->arrayXToNormalized(faceRects[i*4 + 2]);
2137 face.rect[3] = client->arrayYToNormalized(faceRects[i*4 + 3]);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002138
2139 face.score = faceScores[i];
2140 if (faceDetectMode == ANDROID_STATS_FACE_DETECTION_FULL) {
2141 face.id = faceIds[i];
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -07002142 face.left_eye[0] =
2143 client->arrayXToNormalized(faceLandmarks[i*6 + 0]);
2144 face.left_eye[1] =
2145 client->arrayYToNormalized(faceLandmarks[i*6 + 1]);
2146 face.right_eye[0] =
2147 client->arrayXToNormalized(faceLandmarks[i*6 + 2]);
2148 face.right_eye[1] =
2149 client->arrayYToNormalized(faceLandmarks[i*6 + 3]);
2150 face.mouth[0] =
2151 client->arrayXToNormalized(faceLandmarks[i*6 + 4]);
2152 face.mouth[1] =
2153 client->arrayYToNormalized(faceLandmarks[i*6 + 5]);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002154 } else {
2155 face.id = 0;
2156 face.left_eye[0] = face.left_eye[1] = -2000;
2157 face.right_eye[0] = face.right_eye[1] = -2000;
2158 face.mouth[0] = face.mouth[1] = -2000;
2159 }
2160 faces.push_back(face);
2161 }
2162
2163 metadata.faces = faces.editArray();
2164 {
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -07002165 Mutex::Autolock iccl(client->mICameraClientLock);
2166 if (client->mCameraClient != NULL) {
2167 client->mCameraClient->dataCallback(CAMERA_MSG_PREVIEW_METADATA,
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002168 NULL, &metadata);
2169 }
2170 }
2171 }
2172 return OK;
2173}
2174
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002175void Camera2Client::onCallbackAvailable() {
2176 ATRACE_CALL();
2177 status_t res;
2178 ALOGV("%s: Camera %d: Preview callback available", __FUNCTION__, mCameraId);
2179
2180 int callbackHeapId;
2181 sp<Camera2Heap> callbackHeap;
2182 size_t heapIdx;
2183
2184 CpuConsumer::LockedBuffer imgBuffer;
2185 ALOGV("%s: Getting buffer", __FUNCTION__);
2186 res = mCallbackConsumer->lockNextBuffer(&imgBuffer);
2187 if (res != OK) {
2188 ALOGE("%s: Camera %d: Error receiving next callback buffer: "
2189 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2190 return;
2191 }
2192
2193 {
2194 LockedParameters::Key k(mParameters);
2195
2196 if ( k.mParameters.state != PREVIEW && k.mParameters.state != RECORD
2197 && k.mParameters.state != VIDEO_SNAPSHOT) {
2198 ALOGV("%s: Camera %d: No longer streaming",
2199 __FUNCTION__, mCameraId);
2200 mCallbackConsumer->unlockBuffer(imgBuffer);
2201 return;
2202 }
2203
2204 if (! (k.mParameters.previewCallbackFlags &
2205 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) ) {
2206 ALOGV("%s: No longer enabled, dropping", __FUNCTION__);
2207 mCallbackConsumer->unlockBuffer(imgBuffer);
2208 return;
2209 }
2210 if ((k.mParameters.previewCallbackFlags &
2211 CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) &&
2212 !k.mParameters.previewCallbackOneShot) {
2213 ALOGV("%s: One shot mode, already sent, dropping", __FUNCTION__);
2214 mCallbackConsumer->unlockBuffer(imgBuffer);
2215 return;
2216 }
2217
2218 if (imgBuffer.format != k.mParameters.previewFormat) {
2219 ALOGE("%s: Camera %d: Unexpected format for callback: "
2220 "%x, expected %x", __FUNCTION__, mCameraId,
2221 imgBuffer.format, k.mParameters.previewFormat);
2222 mCallbackConsumer->unlockBuffer(imgBuffer);
2223 return;
2224 }
2225
2226 size_t bufferSize = calculateBufferSize(imgBuffer.width, imgBuffer.height,
2227 imgBuffer.format, imgBuffer.stride);
2228 size_t currentBufferSize = (mCallbackHeap == 0) ?
2229 0 : (mCallbackHeap->mHeap->getSize() / kCallbackHeapCount);
2230 if (bufferSize != currentBufferSize) {
2231 mCallbackHeap.clear();
2232 mCallbackHeap = new Camera2Heap(bufferSize, kCallbackHeapCount,
2233 "Camera2Client::CallbackHeap");
2234 if (mCallbackHeap->mHeap->getSize() == 0) {
2235 ALOGE("%s: Camera %d: Unable to allocate memory for callbacks",
2236 __FUNCTION__, mCameraId);
2237 mCallbackConsumer->unlockBuffer(imgBuffer);
2238 return;
2239 }
2240
2241 mCallbackHeapHead = 0;
2242 mCallbackHeapFree = kCallbackHeapCount;
2243 mCallbackHeapId++;
2244 }
2245
2246 if (mCallbackHeapFree == 0) {
2247 ALOGE("%s: Camera %d: No free callback buffers, dropping frame",
2248 __FUNCTION__, mCameraId);
2249 mCallbackConsumer->unlockBuffer(imgBuffer);
2250 return;
2251 }
2252 heapIdx = mCallbackHeapHead;
2253 callbackHeap = mCallbackHeap;
2254 callbackHeapId = mCallbackHeapId;
2255
2256 mCallbackHeapHead = (mCallbackHeapHead + 1) & kCallbackHeapCount;
2257 mCallbackHeapFree--;
2258
2259 // TODO: Get rid of this memcpy by passing the gralloc queue all the way
2260 // to app
2261
2262 ssize_t offset;
2263 size_t size;
2264 sp<IMemoryHeap> heap =
2265 mCallbackHeap->mBuffers[heapIdx]->getMemory(&offset,
2266 &size);
2267 uint8_t *data = (uint8_t*)heap->getBase() + offset;
2268 memcpy(data, imgBuffer.data, bufferSize);
2269
2270 ALOGV("%s: Freeing buffer", __FUNCTION__);
2271 mCallbackConsumer->unlockBuffer(imgBuffer);
2272
2273 // In one-shot mode, stop sending callbacks after the first one
2274 if (k.mParameters.previewCallbackFlags &
2275 CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) {
2276 ALOGV("%s: clearing oneshot", __FUNCTION__);
2277 k.mParameters.previewCallbackOneShot = false;
2278 }
2279 }
2280
2281 // Call outside parameter lock to allow re-entrancy from notification
2282 {
2283 Mutex::Autolock iccl(mICameraClientLock);
2284 if (mCameraClient != 0) {
2285 ALOGV("%s: Camera %d: Invoking client data callback",
2286 __FUNCTION__, mCameraId);
2287 mCameraClient->dataCallback(CAMERA_MSG_PREVIEW_FRAME,
2288 callbackHeap->mBuffers[heapIdx], NULL);
2289 }
2290 }
2291
2292 LockedParameters::Key k(mParameters);
2293 // Only increment free if we're still using the same heap
2294 if (mCallbackHeapId == callbackHeapId) {
2295 mCallbackHeapFree++;
2296 }
2297
2298 ALOGV("%s: exit", __FUNCTION__);
2299}
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002300
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002301void Camera2Client::onCaptureAvailable() {
2302 ATRACE_CALL();
2303 status_t res;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002304 sp<Camera2Heap> captureHeap;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002305 ALOGV("%s: Camera %d: Still capture available", __FUNCTION__, mCameraId);
2306
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002307 {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002308 LockedParameters::Key k(mParameters);
2309 CpuConsumer::LockedBuffer imgBuffer;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002310
2311 res = mCaptureConsumer->lockNextBuffer(&imgBuffer);
2312 if (res != OK) {
2313 ALOGE("%s: Camera %d: Error receiving still image buffer: %s (%d)",
2314 __FUNCTION__, mCameraId, strerror(-res), res);
2315 return;
2316 }
2317
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002318 // TODO: Signal errors here upstream
2319 if (k.mParameters.state != STILL_CAPTURE &&
2320 k.mParameters.state != VIDEO_SNAPSHOT) {
2321 ALOGE("%s: Camera %d: Still image produced unexpectedly!",
2322 __FUNCTION__, mCameraId);
2323 mCaptureConsumer->unlockBuffer(imgBuffer);
2324 return;
2325 }
2326
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002327 if (imgBuffer.format != HAL_PIXEL_FORMAT_BLOB) {
2328 ALOGE("%s: Camera %d: Unexpected format for still image: "
2329 "%x, expected %x", __FUNCTION__, mCameraId,
2330 imgBuffer.format,
2331 HAL_PIXEL_FORMAT_BLOB);
2332 mCaptureConsumer->unlockBuffer(imgBuffer);
2333 return;
2334 }
2335
2336 // TODO: Optimize this to avoid memcopy
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002337 void* captureMemory = mCaptureHeap->mHeap->getBase();
2338 size_t size = mCaptureHeap->mHeap->getSize();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002339 memcpy(captureMemory, imgBuffer.data, size);
2340
2341 mCaptureConsumer->unlockBuffer(imgBuffer);
2342
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002343 switch (k.mParameters.state) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002344 case STILL_CAPTURE:
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002345 k.mParameters.state = STOPPED;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002346 break;
2347 case VIDEO_SNAPSHOT:
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002348 k.mParameters.state = RECORD;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002349 break;
2350 default:
2351 ALOGE("%s: Camera %d: Unexpected state %d", __FUNCTION__,
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002352 mCameraId, k.mParameters.state);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002353 break;
2354 }
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002355
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002356 captureHeap = mCaptureHeap;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002357 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002358 // Call outside parameter locks to allow re-entrancy from notification
2359 Mutex::Autolock iccl(mICameraClientLock);
2360 if (mCameraClient != 0) {
2361 mCameraClient->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE,
2362 captureHeap->mBuffers[0], NULL);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002363 }
2364}
2365
2366void Camera2Client::onRecordingFrameAvailable() {
2367 ATRACE_CALL();
2368 status_t res;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002369 sp<Camera2Heap> recordingHeap;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002370 size_t heapIdx = 0;
2371 nsecs_t timestamp;
2372 {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002373 LockedParameters::Key k(mParameters);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002374
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07002375 BufferItemConsumer::BufferItem imgBuffer;
2376 res = mRecordingConsumer->acquireBuffer(&imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002377 if (res != OK) {
2378 ALOGE("%s: Camera %d: Error receiving recording buffer: %s (%d)",
2379 __FUNCTION__, mCameraId, strerror(-res), res);
2380 return;
2381 }
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07002382 timestamp = imgBuffer.mTimestamp;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002383
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002384 mRecordingFrameCount++;
2385 ALOGV("OnRecordingFrame: Frame %d", mRecordingFrameCount);
2386
2387 // TODO: Signal errors here upstream
2388 if (k.mParameters.state != RECORD &&
2389 k.mParameters.state != VIDEO_SNAPSHOT) {
2390 ALOGV("%s: Camera %d: Discarding recording image buffers received after "
2391 "recording done",
2392 __FUNCTION__, mCameraId);
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07002393 mRecordingConsumer->releaseBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002394 return;
2395 }
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07002396
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002397 if (mRecordingHeap == 0) {
2398 const size_t bufferSize = 4 + sizeof(buffer_handle_t);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002399 ALOGV("%s: Camera %d: Creating recording heap with %d buffers of "
2400 "size %d bytes", __FUNCTION__, mCameraId,
James Dong983cf232012-08-01 16:39:55 -07002401 mRecordingHeapCount, bufferSize);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002402
James Dong983cf232012-08-01 16:39:55 -07002403 mRecordingHeap = new Camera2Heap(bufferSize, mRecordingHeapCount,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002404 "Camera2Client::RecordingHeap");
2405 if (mRecordingHeap->mHeap->getSize() == 0) {
2406 ALOGE("%s: Camera %d: Unable to allocate memory for recording",
2407 __FUNCTION__, mCameraId);
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07002408 mRecordingConsumer->releaseBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002409 return;
2410 }
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07002411 for (size_t i = 0; i < mRecordingBuffers.size(); i++) {
2412 if (mRecordingBuffers[i].mBuf !=
2413 BufferItemConsumer::INVALID_BUFFER_SLOT) {
2414 ALOGE("%s: Camera %d: Non-empty recording buffers list!",
2415 __FUNCTION__, mCameraId);
2416 }
2417 }
2418 mRecordingBuffers.clear();
2419 mRecordingBuffers.setCapacity(mRecordingHeapCount);
2420 mRecordingBuffers.insertAt(0, mRecordingHeapCount);
2421
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002422 mRecordingHeapHead = 0;
James Dong983cf232012-08-01 16:39:55 -07002423 mRecordingHeapFree = mRecordingHeapCount;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002424 }
2425
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002426 if ( mRecordingHeapFree == 0) {
2427 ALOGE("%s: Camera %d: No free recording buffers, dropping frame",
2428 __FUNCTION__, mCameraId);
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07002429 mRecordingConsumer->releaseBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002430 return;
2431 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002432
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002433 heapIdx = mRecordingHeapHead;
James Dong983cf232012-08-01 16:39:55 -07002434 mRecordingHeapHead = (mRecordingHeapHead + 1) % mRecordingHeapCount;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002435 mRecordingHeapFree--;
2436
2437 ALOGV("%s: Camera %d: Timestamp %lld",
2438 __FUNCTION__, mCameraId, timestamp);
2439
2440 ssize_t offset;
2441 size_t size;
2442 sp<IMemoryHeap> heap =
2443 mRecordingHeap->mBuffers[heapIdx]->getMemory(&offset,
2444 &size);
2445
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002446 uint8_t *data = (uint8_t*)heap->getBase() + offset;
2447 uint32_t type = kMetadataBufferTypeGrallocSource;
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07002448 *((uint32_t*)data) = type;
2449 *((buffer_handle_t*)(data + 4)) = imgBuffer.mGraphicBuffer->handle;
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002450 ALOGV("%s: Camera %d: Sending out buffer_handle_t %p",
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07002451 __FUNCTION__, mCameraId, imgBuffer.mGraphicBuffer->handle);
2452 mRecordingBuffers.replaceAt(imgBuffer, heapIdx);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002453 recordingHeap = mRecordingHeap;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002454 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002455
2456 // Call outside locked parameters to allow re-entrancy from notification
2457 Mutex::Autolock iccl(mICameraClientLock);
2458 if (mCameraClient != 0) {
2459 mCameraClient->dataCallbackTimestamp(timestamp,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002460 CAMERA_MSG_VIDEO_FRAME,
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002461 recordingHeap->mBuffers[heapIdx]);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002462 }
2463}
2464
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002465camera_metadata_ro_entry_t Camera2Client::staticInfo(uint32_t tag,
2466 size_t minCount, size_t maxCount) const {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002467 status_t res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002468 camera_metadata_ro_entry_t entry = mDevice->info().find(tag);
2469
2470 if (CC_UNLIKELY( entry.count == 0 )) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002471 const char* tagSection = get_camera_metadata_section_name(tag);
2472 if (tagSection == NULL) tagSection = "<unknown>";
2473 const char* tagName = get_camera_metadata_tag_name(tag);
2474 if (tagName == NULL) tagName = "<unknown>";
2475
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002476 ALOGE("Error finding static metadata entry '%s.%s' (%x)",
2477 tagSection, tagName, tag);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002478 } else if (CC_UNLIKELY(
2479 (minCount != 0 && entry.count < minCount) ||
2480 (maxCount != 0 && entry.count > maxCount) ) ) {
2481 const char* tagSection = get_camera_metadata_section_name(tag);
2482 if (tagSection == NULL) tagSection = "<unknown>";
2483 const char* tagName = get_camera_metadata_tag_name(tag);
2484 if (tagName == NULL) tagName = "<unknown>";
2485 ALOGE("Malformed static metadata entry '%s.%s' (%x):"
2486 "Expected between %d and %d values, but got %d values",
2487 tagSection, tagName, tag, minCount, maxCount, entry.count);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002488 }
2489
2490 return entry;
2491}
2492
2493/** Utility methods */
2494
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002495status_t Camera2Client::buildDeviceInfo() {
2496 if (mDeviceInfo != NULL) {
2497 delete mDeviceInfo;
2498 }
2499 DeviceInfo *deviceInfo = new DeviceInfo;
2500 mDeviceInfo = deviceInfo;
2501
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002502 camera_metadata_ro_entry_t activeArraySize =
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002503 staticInfo(ANDROID_SENSOR_ACTIVE_ARRAY_SIZE, 2, 2);
2504 if (!activeArraySize.count) return NO_INIT;
2505 deviceInfo->arrayWidth = activeArraySize.data.i32[0];
2506 deviceInfo->arrayHeight = activeArraySize.data.i32[1];
2507
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002508 camera_metadata_ro_entry_t availableFaceDetectModes =
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002509 staticInfo(ANDROID_STATS_AVAILABLE_FACE_DETECT_MODES);
2510 if (!availableFaceDetectModes.count) return NO_INIT;
2511
2512 deviceInfo->bestFaceDetectMode =
2513 ANDROID_STATS_FACE_DETECTION_OFF;
2514 for (size_t i = 0 ; i < availableFaceDetectModes.count; i++) {
2515 switch (availableFaceDetectModes.data.u8[i]) {
2516 case ANDROID_STATS_FACE_DETECTION_OFF:
2517 break;
2518 case ANDROID_STATS_FACE_DETECTION_SIMPLE:
2519 if (deviceInfo->bestFaceDetectMode !=
2520 ANDROID_STATS_FACE_DETECTION_FULL) {
2521 deviceInfo->bestFaceDetectMode =
2522 ANDROID_STATS_FACE_DETECTION_SIMPLE;
2523 }
2524 break;
2525 case ANDROID_STATS_FACE_DETECTION_FULL:
2526 deviceInfo->bestFaceDetectMode =
2527 ANDROID_STATS_FACE_DETECTION_FULL;
2528 break;
2529 default:
2530 ALOGE("%s: Camera %d: Unknown face detect mode %d:",
2531 __FUNCTION__, mCameraId,
2532 availableFaceDetectModes.data.u8[i]);
2533 return NO_INIT;
2534 }
2535 }
2536
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002537 camera_metadata_ro_entry_t maxFacesDetected =
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002538 staticInfo(ANDROID_STATS_MAX_FACE_COUNT, 1, 1);
2539 if (!maxFacesDetected.count) return NO_INIT;
2540
2541 deviceInfo->maxFaces = maxFacesDetected.data.i32[0];
2542
2543 return OK;
2544}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002545
2546status_t Camera2Client::buildDefaultParameters() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07002547 ATRACE_CALL();
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002548 LockedParameters::Key k(mParameters);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07002549
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002550 status_t res;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002551 CameraParameters params;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002552
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002553 camera_metadata_ro_entry_t availableProcessedSizes =
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002554 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES, 2);
2555 if (!availableProcessedSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002556
2557 // TODO: Pick more intelligently
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002558 k.mParameters.previewWidth = availableProcessedSizes.data.i32[0];
2559 k.mParameters.previewHeight = availableProcessedSizes.data.i32[1];
2560 k.mParameters.videoWidth = k.mParameters.previewWidth;
2561 k.mParameters.videoHeight = k.mParameters.previewHeight;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002562
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002563 params.setPreviewSize(k.mParameters.previewWidth, k.mParameters.previewHeight);
2564 params.setVideoSize(k.mParameters.videoWidth, k.mParameters.videoHeight);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002565 params.set(CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO,
2566 String8::format("%dx%d",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002567 k.mParameters.previewWidth, k.mParameters.previewHeight));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002568 {
2569 String8 supportedPreviewSizes;
2570 for (size_t i=0; i < availableProcessedSizes.count; i += 2) {
2571 if (i != 0) supportedPreviewSizes += ",";
2572 supportedPreviewSizes += String8::format("%dx%d",
2573 availableProcessedSizes.data.i32[i],
2574 availableProcessedSizes.data.i32[i+1]);
2575 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002576 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002577 supportedPreviewSizes);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002578 params.set(CameraParameters::KEY_SUPPORTED_VIDEO_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002579 supportedPreviewSizes);
2580 }
2581
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002582 camera_metadata_ro_entry_t availableFpsRanges =
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002583 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
2584 if (!availableFpsRanges.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002585
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002586 k.mParameters.previewFpsRange[0] = availableFpsRanges.data.i32[0];
2587 k.mParameters.previewFpsRange[1] = availableFpsRanges.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002588
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002589 params.set(CameraParameters::KEY_PREVIEW_FPS_RANGE,
2590 String8::format("%d,%d",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002591 k.mParameters.previewFpsRange[0],
2592 k.mParameters.previewFpsRange[1]));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002593
2594 {
2595 String8 supportedPreviewFpsRange;
2596 for (size_t i=0; i < availableFpsRanges.count; i += 2) {
2597 if (i != 0) supportedPreviewFpsRange += ",";
2598 supportedPreviewFpsRange += String8::format("(%d,%d)",
2599 availableFpsRanges.data.i32[i],
2600 availableFpsRanges.data.i32[i+1]);
2601 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002602 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002603 supportedPreviewFpsRange);
2604 }
2605
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002606 k.mParameters.previewFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002607 params.set(CameraParameters::KEY_PREVIEW_FORMAT,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002608 formatEnumToString(k.mParameters.previewFormat)); // NV21
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002609
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002610 k.mParameters.previewTransform = degToTransform(0,
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07002611 mCameraFacing == CAMERA_FACING_FRONT);
2612
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002613 camera_metadata_ro_entry_t availableFormats =
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002614 staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
2615
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002616 {
2617 String8 supportedPreviewFormats;
2618 bool addComma = false;
2619 for (size_t i=0; i < availableFormats.count; i++) {
2620 if (addComma) supportedPreviewFormats += ",";
2621 addComma = true;
2622 switch (availableFormats.data.i32[i]) {
2623 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002624 supportedPreviewFormats +=
2625 CameraParameters::PIXEL_FORMAT_YUV422SP;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002626 break;
2627 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002628 supportedPreviewFormats +=
2629 CameraParameters::PIXEL_FORMAT_YUV420SP;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002630 break;
2631 case HAL_PIXEL_FORMAT_YCbCr_422_I:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002632 supportedPreviewFormats +=
2633 CameraParameters::PIXEL_FORMAT_YUV422I;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002634 break;
2635 case HAL_PIXEL_FORMAT_YV12:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002636 supportedPreviewFormats +=
2637 CameraParameters::PIXEL_FORMAT_YUV420P;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002638 break;
2639 case HAL_PIXEL_FORMAT_RGB_565:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002640 supportedPreviewFormats +=
2641 CameraParameters::PIXEL_FORMAT_RGB565;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002642 break;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07002643 case HAL_PIXEL_FORMAT_RGBA_8888:
2644 supportedPreviewFormats +=
2645 CameraParameters::PIXEL_FORMAT_RGBA8888;
2646 break;
2647 // Not advertizing JPEG, RAW_SENSOR, etc, for preview formats
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002648 case HAL_PIXEL_FORMAT_RAW_SENSOR:
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07002649 case HAL_PIXEL_FORMAT_BLOB:
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002650 addComma = false;
2651 break;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07002652
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002653 default:
2654 ALOGW("%s: Camera %d: Unknown preview format: %x",
2655 __FUNCTION__, mCameraId, availableFormats.data.i32[i]);
2656 addComma = false;
2657 break;
2658 }
2659 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002660 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002661 supportedPreviewFormats);
2662 }
2663
2664 // PREVIEW_FRAME_RATE / SUPPORTED_PREVIEW_FRAME_RATES are deprecated, but
2665 // still have to do something sane for them
2666
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002667 params.set(CameraParameters::KEY_PREVIEW_FRAME_RATE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002668 k.mParameters.previewFpsRange[0]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002669
2670 {
2671 String8 supportedPreviewFrameRates;
2672 for (size_t i=0; i < availableFpsRanges.count; i += 2) {
2673 if (i != 0) supportedPreviewFrameRates += ",";
2674 supportedPreviewFrameRates += String8::format("%d",
2675 availableFpsRanges.data.i32[i]);
2676 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002677 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002678 supportedPreviewFrameRates);
2679 }
2680
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002681 camera_metadata_ro_entry_t availableJpegSizes =
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002682 staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES, 2);
2683 if (!availableJpegSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002684
2685 // TODO: Pick maximum
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002686 k.mParameters.pictureWidth = availableJpegSizes.data.i32[0];
2687 k.mParameters.pictureHeight = availableJpegSizes.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002688
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002689 params.setPictureSize(k.mParameters.pictureWidth,
2690 k.mParameters.pictureHeight);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002691
2692 {
2693 String8 supportedPictureSizes;
2694 for (size_t i=0; i < availableJpegSizes.count; i += 2) {
2695 if (i != 0) supportedPictureSizes += ",";
2696 supportedPictureSizes += String8::format("%dx%d",
2697 availableJpegSizes.data.i32[i],
2698 availableJpegSizes.data.i32[i+1]);
2699 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002700 params.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002701 supportedPictureSizes);
2702 }
2703
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002704 params.setPictureFormat(CameraParameters::PIXEL_FORMAT_JPEG);
2705 params.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS,
2706 CameraParameters::PIXEL_FORMAT_JPEG);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002707
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002708 camera_metadata_ro_entry_t availableJpegThumbnailSizes =
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002709 staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES, 2);
2710 if (!availableJpegThumbnailSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002711
2712 // TODO: Pick default thumbnail size sensibly
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002713 k.mParameters.jpegThumbSize[0] = availableJpegThumbnailSizes.data.i32[0];
2714 k.mParameters.jpegThumbSize[1] = availableJpegThumbnailSizes.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002715
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002716 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002717 k.mParameters.jpegThumbSize[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002718 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002719 k.mParameters.jpegThumbSize[1]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002720
2721 {
2722 String8 supportedJpegThumbSizes;
2723 for (size_t i=0; i < availableJpegThumbnailSizes.count; i += 2) {
2724 if (i != 0) supportedJpegThumbSizes += ",";
2725 supportedJpegThumbSizes += String8::format("%dx%d",
2726 availableJpegThumbnailSizes.data.i32[i],
2727 availableJpegThumbnailSizes.data.i32[i+1]);
2728 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002729 params.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002730 supportedJpegThumbSizes);
2731 }
2732
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002733 k.mParameters.jpegThumbQuality = 90;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002734 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002735 k.mParameters.jpegThumbQuality);
2736 k.mParameters.jpegQuality = 90;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002737 params.set(CameraParameters::KEY_JPEG_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002738 k.mParameters.jpegQuality);
2739 k.mParameters.jpegRotation = 0;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002740 params.set(CameraParameters::KEY_ROTATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002741 k.mParameters.jpegRotation);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002742
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002743 k.mParameters.gpsEnabled = false;
2744 k.mParameters.gpsProcessingMethod = "unknown";
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002745 // GPS fields in CameraParameters are not set by implementation
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002746
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002747 k.mParameters.wbMode = ANDROID_CONTROL_AWB_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002748 params.set(CameraParameters::KEY_WHITE_BALANCE,
2749 CameraParameters::WHITE_BALANCE_AUTO);
2750
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002751 camera_metadata_ro_entry_t availableWhiteBalanceModes =
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002752 staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002753 {
2754 String8 supportedWhiteBalance;
2755 bool addComma = false;
2756 for (size_t i=0; i < availableWhiteBalanceModes.count; i++) {
2757 if (addComma) supportedWhiteBalance += ",";
2758 addComma = true;
2759 switch (availableWhiteBalanceModes.data.u8[i]) {
2760 case ANDROID_CONTROL_AWB_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002761 supportedWhiteBalance +=
2762 CameraParameters::WHITE_BALANCE_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002763 break;
2764 case ANDROID_CONTROL_AWB_INCANDESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002765 supportedWhiteBalance +=
2766 CameraParameters::WHITE_BALANCE_INCANDESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002767 break;
2768 case ANDROID_CONTROL_AWB_FLUORESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002769 supportedWhiteBalance +=
2770 CameraParameters::WHITE_BALANCE_FLUORESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002771 break;
2772 case ANDROID_CONTROL_AWB_WARM_FLUORESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002773 supportedWhiteBalance +=
2774 CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002775 break;
2776 case ANDROID_CONTROL_AWB_DAYLIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002777 supportedWhiteBalance +=
2778 CameraParameters::WHITE_BALANCE_DAYLIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002779 break;
2780 case ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002781 supportedWhiteBalance +=
2782 CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002783 break;
2784 case ANDROID_CONTROL_AWB_TWILIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002785 supportedWhiteBalance +=
2786 CameraParameters::WHITE_BALANCE_TWILIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002787 break;
2788 case ANDROID_CONTROL_AWB_SHADE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002789 supportedWhiteBalance +=
2790 CameraParameters::WHITE_BALANCE_SHADE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002791 break;
2792 // Skipping values not mappable to v1 API
2793 case ANDROID_CONTROL_AWB_OFF:
2794 addComma = false;
2795 break;
2796 default:
2797 ALOGW("%s: Camera %d: Unknown white balance value: %d",
2798 __FUNCTION__, mCameraId,
2799 availableWhiteBalanceModes.data.u8[i]);
2800 addComma = false;
2801 break;
2802 }
2803 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002804 params.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002805 supportedWhiteBalance);
2806 }
2807
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002808 k.mParameters.effectMode = ANDROID_CONTROL_EFFECT_OFF;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002809 params.set(CameraParameters::KEY_EFFECT,
2810 CameraParameters::EFFECT_NONE);
2811
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002812 camera_metadata_ro_entry_t availableEffects =
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002813 staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
2814 if (!availableEffects.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002815 {
2816 String8 supportedEffects;
2817 bool addComma = false;
2818 for (size_t i=0; i < availableEffects.count; i++) {
2819 if (addComma) supportedEffects += ",";
2820 addComma = true;
2821 switch (availableEffects.data.u8[i]) {
2822 case ANDROID_CONTROL_EFFECT_OFF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002823 supportedEffects +=
2824 CameraParameters::EFFECT_NONE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002825 break;
2826 case ANDROID_CONTROL_EFFECT_MONO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002827 supportedEffects +=
2828 CameraParameters::EFFECT_MONO;
2829 break;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002830 case ANDROID_CONTROL_EFFECT_NEGATIVE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002831 supportedEffects +=
2832 CameraParameters::EFFECT_NEGATIVE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002833 break;
2834 case ANDROID_CONTROL_EFFECT_SOLARIZE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002835 supportedEffects +=
2836 CameraParameters::EFFECT_SOLARIZE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002837 break;
2838 case ANDROID_CONTROL_EFFECT_SEPIA:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002839 supportedEffects +=
2840 CameraParameters::EFFECT_SEPIA;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002841 break;
2842 case ANDROID_CONTROL_EFFECT_POSTERIZE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002843 supportedEffects +=
2844 CameraParameters::EFFECT_POSTERIZE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002845 break;
2846 case ANDROID_CONTROL_EFFECT_WHITEBOARD:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002847 supportedEffects +=
2848 CameraParameters::EFFECT_WHITEBOARD;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002849 break;
2850 case ANDROID_CONTROL_EFFECT_BLACKBOARD:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002851 supportedEffects +=
2852 CameraParameters::EFFECT_BLACKBOARD;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002853 break;
2854 case ANDROID_CONTROL_EFFECT_AQUA:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002855 supportedEffects +=
2856 CameraParameters::EFFECT_AQUA;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002857 break;
2858 default:
2859 ALOGW("%s: Camera %d: Unknown effect value: %d",
2860 __FUNCTION__, mCameraId, availableEffects.data.u8[i]);
2861 addComma = false;
2862 break;
2863 }
2864 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002865 params.set(CameraParameters::KEY_SUPPORTED_EFFECTS, supportedEffects);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002866 }
2867
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002868 k.mParameters.antibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002869 params.set(CameraParameters::KEY_ANTIBANDING,
2870 CameraParameters::ANTIBANDING_AUTO);
2871
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002872 camera_metadata_ro_entry_t availableAntibandingModes =
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002873 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
2874 if (!availableAntibandingModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002875 {
2876 String8 supportedAntibanding;
2877 bool addComma = false;
2878 for (size_t i=0; i < availableAntibandingModes.count; i++) {
2879 if (addComma) supportedAntibanding += ",";
2880 addComma = true;
2881 switch (availableAntibandingModes.data.u8[i]) {
2882 case ANDROID_CONTROL_AE_ANTIBANDING_OFF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002883 supportedAntibanding +=
2884 CameraParameters::ANTIBANDING_OFF;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002885 break;
2886 case ANDROID_CONTROL_AE_ANTIBANDING_50HZ:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002887 supportedAntibanding +=
2888 CameraParameters::ANTIBANDING_50HZ;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002889 break;
2890 case ANDROID_CONTROL_AE_ANTIBANDING_60HZ:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002891 supportedAntibanding +=
2892 CameraParameters::ANTIBANDING_60HZ;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002893 break;
2894 case ANDROID_CONTROL_AE_ANTIBANDING_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002895 supportedAntibanding +=
2896 CameraParameters::ANTIBANDING_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002897 break;
2898 default:
2899 ALOGW("%s: Camera %d: Unknown antibanding value: %d",
2900 __FUNCTION__, mCameraId,
2901 availableAntibandingModes.data.u8[i]);
2902 addComma = false;
2903 break;
2904 }
2905 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002906 params.set(CameraParameters::KEY_SUPPORTED_ANTIBANDING,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002907 supportedAntibanding);
2908 }
2909
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002910 k.mParameters.sceneMode = ANDROID_CONTROL_OFF;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002911 params.set(CameraParameters::KEY_SCENE_MODE,
2912 CameraParameters::SCENE_MODE_AUTO);
2913
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002914 camera_metadata_ro_entry_t availableSceneModes =
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002915 staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
2916 if (!availableSceneModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002917 {
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002918 String8 supportedSceneModes(CameraParameters::SCENE_MODE_AUTO);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002919 bool addComma = true;
2920 bool noSceneModes = false;
2921 for (size_t i=0; i < availableSceneModes.count; i++) {
2922 if (addComma) supportedSceneModes += ",";
2923 addComma = true;
2924 switch (availableSceneModes.data.u8[i]) {
2925 case ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED:
2926 noSceneModes = true;
2927 break;
2928 case ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY:
2929 // Not in old API
2930 addComma = false;
2931 break;
2932 case ANDROID_CONTROL_SCENE_MODE_ACTION:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002933 supportedSceneModes +=
2934 CameraParameters::SCENE_MODE_ACTION;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002935 break;
2936 case ANDROID_CONTROL_SCENE_MODE_PORTRAIT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002937 supportedSceneModes +=
2938 CameraParameters::SCENE_MODE_PORTRAIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002939 break;
2940 case ANDROID_CONTROL_SCENE_MODE_LANDSCAPE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002941 supportedSceneModes +=
2942 CameraParameters::SCENE_MODE_LANDSCAPE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002943 break;
2944 case ANDROID_CONTROL_SCENE_MODE_NIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002945 supportedSceneModes +=
2946 CameraParameters::SCENE_MODE_NIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002947 break;
2948 case ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002949 supportedSceneModes +=
2950 CameraParameters::SCENE_MODE_NIGHT_PORTRAIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002951 break;
2952 case ANDROID_CONTROL_SCENE_MODE_THEATRE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002953 supportedSceneModes +=
2954 CameraParameters::SCENE_MODE_THEATRE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002955 break;
2956 case ANDROID_CONTROL_SCENE_MODE_BEACH:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002957 supportedSceneModes +=
2958 CameraParameters::SCENE_MODE_BEACH;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002959 break;
2960 case ANDROID_CONTROL_SCENE_MODE_SNOW:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002961 supportedSceneModes +=
2962 CameraParameters::SCENE_MODE_SNOW;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002963 break;
2964 case ANDROID_CONTROL_SCENE_MODE_SUNSET:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002965 supportedSceneModes +=
2966 CameraParameters::SCENE_MODE_SUNSET;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002967 break;
2968 case ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002969 supportedSceneModes +=
2970 CameraParameters::SCENE_MODE_STEADYPHOTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002971 break;
2972 case ANDROID_CONTROL_SCENE_MODE_FIREWORKS:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002973 supportedSceneModes +=
2974 CameraParameters::SCENE_MODE_FIREWORKS;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002975 break;
2976 case ANDROID_CONTROL_SCENE_MODE_SPORTS:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002977 supportedSceneModes +=
2978 CameraParameters::SCENE_MODE_SPORTS;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002979 break;
2980 case ANDROID_CONTROL_SCENE_MODE_PARTY:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002981 supportedSceneModes +=
2982 CameraParameters::SCENE_MODE_PARTY;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002983 break;
2984 case ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002985 supportedSceneModes +=
2986 CameraParameters::SCENE_MODE_CANDLELIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002987 break;
2988 case ANDROID_CONTROL_SCENE_MODE_BARCODE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002989 supportedSceneModes +=
2990 CameraParameters::SCENE_MODE_BARCODE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002991 break;
2992 default:
2993 ALOGW("%s: Camera %d: Unknown scene mode value: %d",
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002994 __FUNCTION__, mCameraId,
2995 availableSceneModes.data.u8[i]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002996 addComma = false;
2997 break;
2998 }
2999 }
3000 if (!noSceneModes) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003001 params.set(CameraParameters::KEY_SUPPORTED_SCENE_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003002 supportedSceneModes);
3003 }
3004 }
3005
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003006 camera_metadata_ro_entry_t flashAvailable =
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003007 staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
3008 if (!flashAvailable.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003009
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003010 camera_metadata_ro_entry_t availableAeModes =
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003011 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
3012 if (!availableAeModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003013
3014 if (flashAvailable.data.u8[0]) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003015 k.mParameters.flashMode = Parameters::FLASH_MODE_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003016 params.set(CameraParameters::KEY_FLASH_MODE,
3017 CameraParameters::FLASH_MODE_AUTO);
3018
3019 String8 supportedFlashModes(CameraParameters::FLASH_MODE_OFF);
3020 supportedFlashModes = supportedFlashModes +
3021 "," + CameraParameters::FLASH_MODE_AUTO +
3022 "," + CameraParameters::FLASH_MODE_ON +
3023 "," + CameraParameters::FLASH_MODE_TORCH;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003024 for (size_t i=0; i < availableAeModes.count; i++) {
3025 if (availableAeModes.data.u8[i] ==
3026 ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003027 supportedFlashModes = supportedFlashModes + "," +
3028 CameraParameters::FLASH_MODE_RED_EYE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003029 break;
3030 }
3031 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003032 params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003033 supportedFlashModes);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003034 } else {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003035 k.mParameters.flashMode = Parameters::FLASH_MODE_OFF;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003036 params.set(CameraParameters::KEY_FLASH_MODE,
3037 CameraParameters::FLASH_MODE_OFF);
3038 params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
3039 CameraParameters::FLASH_MODE_OFF);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003040 }
3041
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003042 camera_metadata_ro_entry_t minFocusDistance =
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003043 staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE, 1, 1);
3044 if (!minFocusDistance.count) return NO_INIT;
3045
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003046 camera_metadata_ro_entry_t availableAfModes =
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003047 staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
3048 if (!availableAfModes.count) return NO_INIT;
3049
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003050 if (minFocusDistance.data.f[0] == 0) {
3051 // Fixed-focus lens
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003052 k.mParameters.focusMode = Parameters::FOCUS_MODE_FIXED;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003053 params.set(CameraParameters::KEY_FOCUS_MODE,
3054 CameraParameters::FOCUS_MODE_FIXED);
3055 params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
3056 CameraParameters::FOCUS_MODE_FIXED);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003057 } else {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003058 k.mParameters.focusMode = Parameters::FOCUS_MODE_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003059 params.set(CameraParameters::KEY_FOCUS_MODE,
3060 CameraParameters::FOCUS_MODE_AUTO);
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07003061 String8 supportedFocusModes(CameraParameters::FOCUS_MODE_INFINITY);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003062 bool addComma = true;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07003063
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003064 for (size_t i=0; i < availableAfModes.count; i++) {
3065 if (addComma) supportedFocusModes += ",";
3066 addComma = true;
3067 switch (availableAfModes.data.u8[i]) {
3068 case ANDROID_CONTROL_AF_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07003069 supportedFocusModes +=
3070 CameraParameters::FOCUS_MODE_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003071 break;
3072 case ANDROID_CONTROL_AF_MACRO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07003073 supportedFocusModes +=
3074 CameraParameters::FOCUS_MODE_MACRO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003075 break;
3076 case ANDROID_CONTROL_AF_CONTINUOUS_VIDEO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07003077 supportedFocusModes +=
3078 CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003079 break;
3080 case ANDROID_CONTROL_AF_CONTINUOUS_PICTURE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07003081 supportedFocusModes +=
3082 CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003083 break;
3084 case ANDROID_CONTROL_AF_EDOF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07003085 supportedFocusModes +=
3086 CameraParameters::FOCUS_MODE_EDOF;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003087 break;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07003088 // Not supported in old API
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003089 case ANDROID_CONTROL_AF_OFF:
3090 addComma = false;
3091 break;
3092 default:
3093 ALOGW("%s: Camera %d: Unknown AF mode value: %d",
3094 __FUNCTION__, mCameraId, availableAfModes.data.u8[i]);
3095 addComma = false;
3096 break;
3097 }
3098 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003099 params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003100 supportedFocusModes);
3101 }
3102
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003103 camera_metadata_ro_entry_t max3aRegions =
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003104 staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1);
3105 if (!max3aRegions.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003106
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003107 params.set(CameraParameters::KEY_MAX_NUM_FOCUS_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003108 max3aRegions.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003109 params.set(CameraParameters::KEY_FOCUS_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003110 "(0,0,0,0,0)");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003111 k.mParameters.focusingAreas.clear();
3112 k.mParameters.focusingAreas.add(Parameters::Area(0,0,0,0,0));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003113
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003114 camera_metadata_ro_entry_t availableFocalLengths =
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003115 staticInfo(ANDROID_LENS_AVAILABLE_FOCAL_LENGTHS);
3116 if (!availableFocalLengths.count) return NO_INIT;
3117
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003118 float minFocalLength = availableFocalLengths.data.f[0];
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003119 params.setFloat(CameraParameters::KEY_FOCAL_LENGTH, minFocalLength);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003120
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003121 camera_metadata_ro_entry_t sensorSize =
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003122 staticInfo(ANDROID_SENSOR_PHYSICAL_SIZE, 2, 2);
3123 if (!sensorSize.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003124
3125 // The fields of view here assume infinity focus, maximum wide angle
3126 float horizFov = 180 / M_PI *
3127 2 * atanf(sensorSize.data.f[0] / (2 * minFocalLength));
3128 float vertFov = 180 / M_PI *
3129 2 * atanf(sensorSize.data.f[1] / (2 * minFocalLength));
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003130 params.setFloat(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, horizFov);
3131 params.setFloat(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, vertFov);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003132
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003133 k.mParameters.exposureCompensation = 0;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003134 params.set(CameraParameters::KEY_EXPOSURE_COMPENSATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003135 k.mParameters.exposureCompensation);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003136
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003137 camera_metadata_ro_entry_t exposureCompensationRange =
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003138 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE, 2, 2);
3139 if (!exposureCompensationRange.count) return NO_INIT;
3140
3141 params.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003142 exposureCompensationRange.data.i32[1]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003143 params.set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003144 exposureCompensationRange.data.i32[0]);
3145
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003146 camera_metadata_ro_entry_t exposureCompensationStep =
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003147 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_STEP, 1, 1);
3148 if (!exposureCompensationStep.count) return NO_INIT;
3149
3150 params.setFloat(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP,
Eino-Ville Talvalad6f8e082012-08-02 16:00:35 -07003151 (float)exposureCompensationStep.data.r[0].numerator /
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003152 exposureCompensationStep.data.r[0].denominator);
3153
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003154 k.mParameters.autoExposureLock = false;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003155 params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK,
3156 CameraParameters::FALSE);
3157 params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED,
3158 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003159
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003160 k.mParameters.autoWhiteBalanceLock = false;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003161 params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK,
3162 CameraParameters::FALSE);
3163 params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED,
3164 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003165
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003166 k.mParameters.meteringAreas.add(Parameters::Area(0, 0, 0, 0, 0));
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003167 params.set(CameraParameters::KEY_MAX_NUM_METERING_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003168 max3aRegions.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003169 params.set(CameraParameters::KEY_METERING_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003170 "(0,0,0,0,0)");
3171
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003172 k.mParameters.zoom = 0;
3173 params.set(CameraParameters::KEY_ZOOM, k.mParameters.zoom);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003174 params.set(CameraParameters::KEY_MAX_ZOOM, NUM_ZOOM_STEPS - 1);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003175
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003176 camera_metadata_ro_entry_t maxDigitalZoom =
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003177 staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM, 1, 1);
3178 if (!maxDigitalZoom.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003179
3180 {
3181 String8 zoomRatios;
3182 float zoom = 1.f;
3183 float zoomIncrement = (maxDigitalZoom.data.f[0] - zoom) /
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07003184 (NUM_ZOOM_STEPS-1);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003185 bool addComma = false;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07003186 for (size_t i=0; i < NUM_ZOOM_STEPS; i++) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003187 if (addComma) zoomRatios += ",";
3188 addComma = true;
3189 zoomRatios += String8::format("%d", static_cast<int>(zoom * 100));
3190 zoom += zoomIncrement;
3191 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003192 params.set(CameraParameters::KEY_ZOOM_RATIOS, zoomRatios);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003193 }
3194
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003195 params.set(CameraParameters::KEY_ZOOM_SUPPORTED,
3196 CameraParameters::TRUE);
3197 params.set(CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED,
3198 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003199
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003200 params.set(CameraParameters::KEY_FOCUS_DISTANCES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003201 "Infinity,Infinity,Infinity");
3202
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003203 params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW,
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003204 mDeviceInfo->maxFaces);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003205 params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003206 0);
3207
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003208 params.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT,
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07003209 CameraParameters::PIXEL_FORMAT_ANDROID_OPAQUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003210
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003211 params.set(CameraParameters::KEY_RECORDING_HINT,
3212 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003213
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003214 params.set(CameraParameters::KEY_VIDEO_SNAPSHOT_SUPPORTED,
3215 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003216
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003217 params.set(CameraParameters::KEY_VIDEO_STABILIZATION,
3218 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003219
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003220 camera_metadata_ro_entry_t availableVideoStabilizationModes =
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003221 staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
3222 if (!availableVideoStabilizationModes.count) return NO_INIT;
3223
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003224 if (availableVideoStabilizationModes.count > 1) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003225 params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
3226 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003227 } else {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003228 params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
3229 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003230 }
3231
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07003232 // Set up initial state for non-Camera.Parameters state variables
3233
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003234 k.mParameters.storeMetadataInBuffers = true;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07003235 k.mParameters.playShutterSound = true;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003236 k.mParameters.enableFaceDetect = false;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07003237
3238 k.mParameters.enableFocusMoveMessages = false;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07003239 k.mParameters.afTriggerCounter = 0;
3240 k.mParameters.currentAfTriggerId = -1;
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07003241
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07003242 k.mParameters.previewCallbackFlags = 0;
3243
3244 k.mParameters.state = STOPPED;
3245
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003246 k.mParameters.paramsFlattened = params.flatten();
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003247
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07003248 return OK;
3249}
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07003250
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003251status_t Camera2Client::updateRequests(const Parameters &params) {
3252 status_t res;
3253
3254 res = updatePreviewRequest(params);
3255 if (res != OK) {
3256 ALOGE("%s: Camera %d: Unable to update preview request: %s (%d)",
3257 __FUNCTION__, mCameraId, strerror(-res), res);
3258 return res;
3259 }
3260 res = updateCaptureRequest(params);
3261 if (res != OK) {
3262 ALOGE("%s: Camera %d: Unable to update capture request: %s (%d)",
3263 __FUNCTION__, mCameraId, strerror(-res), res);
3264 return res;
3265 }
3266
3267 res = updateRecordingRequest(params);
3268 if (res != OK) {
3269 ALOGE("%s: Camera %d: Unable to update recording request: %s (%d)",
3270 __FUNCTION__, mCameraId, strerror(-res), res);
3271 return res;
3272 }
3273
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07003274 if (params.state == PREVIEW) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003275 res = mDevice->setStreamingRequest(mPreviewRequest);
3276 if (res != OK) {
3277 ALOGE("%s: Camera %d: Error streaming new preview request: %s (%d)",
3278 __FUNCTION__, mCameraId, strerror(-res), res);
3279 return res;
3280 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07003281 } else if (params.state == RECORD || params.state == VIDEO_SNAPSHOT) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003282 res = mDevice->setStreamingRequest(mRecordingRequest);
3283 if (res != OK) {
3284 ALOGE("%s: Camera %d: Error streaming new record request: %s (%d)",
3285 __FUNCTION__, mCameraId, strerror(-res), res);
3286 return res;
3287 }
3288 }
3289 return res;
3290}
3291
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003292status_t Camera2Client::updatePreviewStream(const Parameters &params) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003293 ATRACE_CALL();
3294 status_t res;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003295
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003296 if (mPreviewStreamId != NO_STREAM) {
3297 // Check if stream parameters have to change
3298 uint32_t currentWidth, currentHeight;
3299 res = mDevice->getStreamInfo(mPreviewStreamId,
3300 &currentWidth, &currentHeight, 0);
3301 if (res != OK) {
3302 ALOGE("%s: Camera %d: Error querying preview stream info: "
3303 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3304 return res;
3305 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003306 if (currentWidth != (uint32_t)params.previewWidth ||
3307 currentHeight != (uint32_t)params.previewHeight) {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -07003308 ALOGV("%s: Camera %d: Preview size switch: %d x %d -> %d x %d",
3309 __FUNCTION__, mCameraId, currentWidth, currentHeight,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003310 params.previewWidth, params.previewHeight);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003311 res = mDevice->waitUntilDrained();
3312 if (res != OK) {
3313 ALOGE("%s: Camera %d: Error waiting for preview to drain: "
3314 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3315 return res;
3316 }
3317 res = mDevice->deleteStream(mPreviewStreamId);
3318 if (res != OK) {
3319 ALOGE("%s: Camera %d: Unable to delete old output stream "
3320 "for preview: %s (%d)", __FUNCTION__, mCameraId,
3321 strerror(-res), res);
3322 return res;
3323 }
3324 mPreviewStreamId = NO_STREAM;
3325 }
3326 }
3327
3328 if (mPreviewStreamId == NO_STREAM) {
3329 res = mDevice->createStream(mPreviewWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003330 params.previewWidth, params.previewHeight,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003331 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0,
3332 &mPreviewStreamId);
3333 if (res != OK) {
3334 ALOGE("%s: Camera %d: Unable to create preview stream: %s (%d)",
3335 __FUNCTION__, mCameraId, strerror(-res), res);
3336 return res;
3337 }
3338 }
3339
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07003340 res = mDevice->setStreamTransform(mPreviewStreamId,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003341 params.previewTransform);
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07003342 if (res != OK) {
3343 ALOGE("%s: Camera %d: Unable to set preview stream transform: "
3344 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3345 return res;
3346 }
3347
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003348 return OK;
3349}
3350
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003351status_t Camera2Client::updatePreviewRequest(const Parameters &params) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07003352 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07003353 status_t res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003354 if (mPreviewRequest.entryCount() == 0) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07003355 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
3356 &mPreviewRequest);
3357 if (res != OK) {
3358 ALOGE("%s: Camera %d: Unable to create default preview request: "
3359 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3360 return res;
3361 }
3362 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003363
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003364 res = updateRequestCommon(&mPreviewRequest, params);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003365 if (res != OK) {
3366 ALOGE("%s: Camera %d: Unable to update common entries of preview "
3367 "request: %s (%d)", __FUNCTION__, mCameraId,
3368 strerror(-res), res);
3369 return res;
3370 }
3371
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07003372 return OK;
3373}
3374
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07003375status_t Camera2Client::updateCallbackStream(const Parameters &params) {
3376 status_t res;
3377
3378 if (mCallbackConsumer == 0) {
3379 // Create CPU buffer queue endpoint
3380 mCallbackConsumer = new CpuConsumer(kCallbackHeapCount);
3381 mCallbackWaiter = new CallbackWaiter(this);
3382 mCallbackConsumer->setFrameAvailableListener(mCallbackWaiter);
3383 mCallbackConsumer->setName(String8("Camera2Client::CallbackConsumer"));
3384 mCallbackWindow = new SurfaceTextureClient(
3385 mCallbackConsumer->getProducerInterface());
3386 }
3387
3388 if (mCallbackStreamId != NO_STREAM) {
3389 // Check if stream parameters have to change
3390 uint32_t currentWidth, currentHeight, currentFormat;
3391 res = mDevice->getStreamInfo(mCallbackStreamId,
3392 &currentWidth, &currentHeight, &currentFormat);
3393 if (res != OK) {
3394 ALOGE("%s: Camera %d: Error querying callback output stream info: "
3395 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3396 return res;
3397 }
3398 if (currentWidth != (uint32_t)params.previewWidth ||
3399 currentHeight != (uint32_t)params.previewHeight ||
3400 currentFormat != (uint32_t)params.previewFormat) {
3401 // Since size should only change while preview is not running,
3402 // assuming that all existing use of old callback stream is
3403 // completed.
3404 res = mDevice->deleteStream(mCallbackStreamId);
3405 if (res != OK) {
3406 ALOGE("%s: Camera %d: Unable to delete old output stream "
3407 "for callbacks: %s (%d)", __FUNCTION__, mCameraId,
3408 strerror(-res), res);
3409 return res;
3410 }
3411 mCallbackStreamId = NO_STREAM;
3412 }
3413 }
3414
3415 if (mCallbackStreamId == NO_STREAM) {
3416 ALOGV("Creating callback stream: %d %d format 0x%x",
3417 params.previewWidth, params.previewHeight,
3418 params.previewFormat);
3419 res = mDevice->createStream(mCallbackWindow,
3420 params.previewWidth, params.previewHeight,
3421 params.previewFormat, 0, &mCallbackStreamId);
3422 if (res != OK) {
3423 ALOGE("%s: Camera %d: Can't create output stream for callbacks: "
3424 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3425 return res;
3426 }
3427 }
3428
3429 return OK;
3430}
3431
3432
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003433status_t Camera2Client::updateCaptureStream(const Parameters &params) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003434 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003435 status_t res;
3436 // Find out buffer size for JPEG
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003437 camera_metadata_ro_entry_t maxJpegSize =
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003438 staticInfo(ANDROID_JPEG_MAX_SIZE);
3439 if (maxJpegSize.count == 0) {
3440 ALOGE("%s: Camera %d: Can't find ANDROID_JPEG_MAX_SIZE!",
3441 __FUNCTION__, mCameraId);
3442 return INVALID_OPERATION;
3443 }
3444
3445 if (mCaptureConsumer == 0) {
3446 // Create CPU buffer queue endpoint
3447 mCaptureConsumer = new CpuConsumer(1);
3448 mCaptureConsumer->setFrameAvailableListener(new CaptureWaiter(this));
3449 mCaptureConsumer->setName(String8("Camera2Client::CaptureConsumer"));
3450 mCaptureWindow = new SurfaceTextureClient(
3451 mCaptureConsumer->getProducerInterface());
3452 // Create memory for API consumption
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07003453 mCaptureHeap = new Camera2Heap(maxJpegSize.data.i32[0], 1,
3454 "Camera2Client::CaptureHeap");
3455 if (mCaptureHeap->mHeap->getSize() == 0) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003456 ALOGE("%s: Camera %d: Unable to allocate memory for capture",
3457 __FUNCTION__, mCameraId);
3458 return NO_MEMORY;
3459 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003460 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003461
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003462 if (mCaptureStreamId != NO_STREAM) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003463 // Check if stream parameters have to change
3464 uint32_t currentWidth, currentHeight;
3465 res = mDevice->getStreamInfo(mCaptureStreamId,
3466 &currentWidth, &currentHeight, 0);
3467 if (res != OK) {
3468 ALOGE("%s: Camera %d: Error querying capture output stream info: "
3469 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3470 return res;
3471 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003472 if (currentWidth != (uint32_t)params.pictureWidth ||
3473 currentHeight != (uint32_t)params.pictureHeight) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003474 res = mDevice->deleteStream(mCaptureStreamId);
3475 if (res != OK) {
3476 ALOGE("%s: Camera %d: Unable to delete old output stream "
3477 "for capture: %s (%d)", __FUNCTION__, mCameraId,
3478 strerror(-res), res);
3479 return res;
3480 }
3481 mCaptureStreamId = NO_STREAM;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003482 }
3483 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003484
3485 if (mCaptureStreamId == NO_STREAM) {
3486 // Create stream for HAL production
3487 res = mDevice->createStream(mCaptureWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003488 params.pictureWidth, params.pictureHeight,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003489 HAL_PIXEL_FORMAT_BLOB, maxJpegSize.data.i32[0],
3490 &mCaptureStreamId);
3491 if (res != OK) {
3492 ALOGE("%s: Camera %d: Can't create output stream for capture: "
3493 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3494 return res;
3495 }
3496
3497 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003498 return OK;
3499}
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003500
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003501status_t Camera2Client::updateCaptureRequest(const Parameters &params) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003502 ATRACE_CALL();
3503 status_t res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003504 if (mCaptureRequest.entryCount() == 0) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003505 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_STILL_CAPTURE,
3506 &mCaptureRequest);
3507 if (res != OK) {
3508 ALOGE("%s: Camera %d: Unable to create default still image request:"
3509 " %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3510 return res;
3511 }
3512 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003513
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003514 res = updateRequestCommon(&mCaptureRequest, params);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003515 if (res != OK) {
3516 ALOGE("%s: Camera %d: Unable to update common entries of capture "
3517 "request: %s (%d)", __FUNCTION__, mCameraId,
3518 strerror(-res), res);
3519 return res;
3520 }
3521
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003522 res = mCaptureRequest.update(ANDROID_JPEG_THUMBNAIL_SIZE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003523 params.jpegThumbSize, 2);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003524 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003525 res = mCaptureRequest.update(ANDROID_JPEG_THUMBNAIL_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003526 &params.jpegThumbQuality, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003527 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003528 res = mCaptureRequest.update(ANDROID_JPEG_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003529 &params.jpegQuality, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003530 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003531 res = mCaptureRequest.update(
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003532 ANDROID_JPEG_ORIENTATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003533 &params.jpegRotation, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003534 if (res != OK) return res;
3535
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003536 if (params.gpsEnabled) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003537 res = mCaptureRequest.update(
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003538 ANDROID_JPEG_GPS_COORDINATES,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003539 params.gpsCoordinates, 3);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003540 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003541 res = mCaptureRequest.update(
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003542 ANDROID_JPEG_GPS_TIMESTAMP,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003543 &params.gpsTimestamp, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003544 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003545 res = mCaptureRequest.update(
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003546 ANDROID_JPEG_GPS_PROCESSING_METHOD,
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003547 params.gpsProcessingMethod);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003548 if (res != OK) return res;
3549 } else {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003550 res = mCaptureRequest.erase(ANDROID_JPEG_GPS_COORDINATES);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003551 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003552 res = mCaptureRequest.erase(ANDROID_JPEG_GPS_TIMESTAMP);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003553 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003554 res = mCaptureRequest.erase(ANDROID_JPEG_GPS_PROCESSING_METHOD);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003555 if (res != OK) return res;
3556 }
3557
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07003558 return OK;
3559}
3560
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003561status_t Camera2Client::updateRecordingRequest(const Parameters &params) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07003562 ATRACE_CALL();
3563 status_t res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003564 if (mRecordingRequest.entryCount() == 0) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07003565 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_VIDEO_RECORD,
3566 &mRecordingRequest);
3567 if (res != OK) {
3568 ALOGE("%s: Camera %d: Unable to create default recording request:"
3569 " %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3570 return res;
3571 }
3572 }
3573
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003574 res = updateRequestCommon(&mRecordingRequest, params);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07003575 if (res != OK) {
3576 ALOGE("%s: Camera %d: Unable to update common entries of recording "
3577 "request: %s (%d)", __FUNCTION__, mCameraId,
3578 strerror(-res), res);
3579 return res;
3580 }
3581
3582 return OK;
3583}
3584
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003585status_t Camera2Client::updateRecordingStream(const Parameters &params) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07003586 status_t res;
3587
3588 if (mRecordingConsumer == 0) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07003589 // Create CPU buffer queue endpoint. We need one more buffer here so that we can
3590 // always acquire and free a buffer when the heap is full; otherwise the consumer
3591 // will have buffers in flight we'll never clear out.
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07003592 mRecordingConsumer = new BufferItemConsumer(
3593 GRALLOC_USAGE_HW_VIDEO_ENCODER,
3594 mRecordingHeapCount + 1,
3595 true);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07003596 mRecordingConsumer->setFrameAvailableListener(new RecordingWaiter(this));
3597 mRecordingConsumer->setName(String8("Camera2Client::RecordingConsumer"));
3598 mRecordingWindow = new SurfaceTextureClient(
3599 mRecordingConsumer->getProducerInterface());
3600 // Allocate memory later, since we don't know buffer size until receipt
3601 }
3602
3603 if (mRecordingStreamId != NO_STREAM) {
3604 // Check if stream parameters have to change
3605 uint32_t currentWidth, currentHeight;
3606 res = mDevice->getStreamInfo(mRecordingStreamId,
3607 &currentWidth, &currentHeight, 0);
3608 if (res != OK) {
3609 ALOGE("%s: Camera %d: Error querying recording output stream info: "
3610 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3611 return res;
3612 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003613 if (currentWidth != (uint32_t)params.videoWidth ||
3614 currentHeight != (uint32_t)params.videoHeight) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07003615 // TODO: Should wait to be sure previous recording has finished
3616 res = mDevice->deleteStream(mRecordingStreamId);
3617 if (res != OK) {
3618 ALOGE("%s: Camera %d: Unable to delete old output stream "
3619 "for recording: %s (%d)", __FUNCTION__, mCameraId,
3620 strerror(-res), res);
3621 return res;
3622 }
3623 mRecordingStreamId = NO_STREAM;
3624 }
3625 }
3626
3627 if (mRecordingStreamId == NO_STREAM) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07003628 mRecordingFrameCount = 0;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07003629 res = mDevice->createStream(mRecordingWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003630 params.videoWidth, params.videoHeight,
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07003631 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0, &mRecordingStreamId);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07003632 if (res != OK) {
3633 ALOGE("%s: Camera %d: Can't create output stream for recording: "
3634 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
3635 return res;
3636 }
3637 }
3638
3639 return OK;
3640}
3641
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003642status_t Camera2Client::updateRequestCommon(CameraMetadata *request,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003643 const Parameters &params) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003644 ATRACE_CALL();
3645 status_t res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003646 res = request->update(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
3647 params.previewFpsRange, 2);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003648 if (res != OK) return res;
3649
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003650 uint8_t wbMode = params.autoWhiteBalanceLock ?
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003651 (uint8_t)ANDROID_CONTROL_AWB_LOCKED : params.wbMode;
3652 res = request->update(ANDROID_CONTROL_AWB_MODE,
3653 &wbMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003654 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003655 res = request->update(ANDROID_CONTROL_EFFECT_MODE,
3656 &params.effectMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003657 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003658 res = request->update(ANDROID_CONTROL_AE_ANTIBANDING_MODE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003659 &params.antibandingMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003660 if (res != OK) return res;
3661
3662 uint8_t controlMode =
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003663 (params.sceneMode == ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED) ?
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003664 ANDROID_CONTROL_AUTO : ANDROID_CONTROL_USE_SCENE_MODE;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003665 res = request->update(ANDROID_CONTROL_MODE,
3666 &controlMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003667 if (res != OK) return res;
3668 if (controlMode == ANDROID_CONTROL_USE_SCENE_MODE) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003669 res = request->update(ANDROID_CONTROL_SCENE_MODE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003670 &params.sceneMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003671 if (res != OK) return res;
3672 }
3673
3674 uint8_t flashMode = ANDROID_FLASH_OFF;
3675 uint8_t aeMode;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003676 switch (params.flashMode) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003677 case Parameters::FLASH_MODE_OFF:
3678 aeMode = ANDROID_CONTROL_AE_ON; break;
3679 case Parameters::FLASH_MODE_AUTO:
3680 aeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH; break;
3681 case Parameters::FLASH_MODE_ON:
3682 aeMode = ANDROID_CONTROL_AE_ON_ALWAYS_FLASH; break;
3683 case Parameters::FLASH_MODE_TORCH:
3684 aeMode = ANDROID_CONTROL_AE_ON;
3685 flashMode = ANDROID_FLASH_TORCH;
3686 break;
3687 case Parameters::FLASH_MODE_RED_EYE:
3688 aeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE; break;
3689 default:
3690 ALOGE("%s: Camera %d: Unknown flash mode %d", __FUNCTION__,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003691 mCameraId, params.flashMode);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003692 return BAD_VALUE;
3693 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003694 if (params.autoExposureLock) aeMode = ANDROID_CONTROL_AE_LOCKED;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003695
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003696 res = request->update(ANDROID_FLASH_MODE,
3697 &flashMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003698 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003699 res = request->update(ANDROID_CONTROL_AE_MODE,
3700 &aeMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003701 if (res != OK) return res;
3702
3703 float focusDistance = 0; // infinity focus in diopters
3704 uint8_t focusMode;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003705 switch (params.focusMode) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003706 case Parameters::FOCUS_MODE_AUTO:
3707 case Parameters::FOCUS_MODE_MACRO:
3708 case Parameters::FOCUS_MODE_CONTINUOUS_VIDEO:
3709 case Parameters::FOCUS_MODE_CONTINUOUS_PICTURE:
3710 case Parameters::FOCUS_MODE_EDOF:
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003711 focusMode = params.focusMode;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003712 break;
3713 case Parameters::FOCUS_MODE_INFINITY:
3714 case Parameters::FOCUS_MODE_FIXED:
3715 focusMode = ANDROID_CONTROL_AF_OFF;
3716 break;
3717 default:
3718 ALOGE("%s: Camera %d: Unknown focus mode %d", __FUNCTION__,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003719 mCameraId, params.focusMode);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003720 return BAD_VALUE;
3721 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003722 res = request->update(ANDROID_LENS_FOCUS_DISTANCE,
3723 &focusDistance, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003724 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003725 res = request->update(ANDROID_CONTROL_AF_MODE,
3726 &focusMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003727 if (res != OK) return res;
3728
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003729 size_t focusingAreasSize = params.focusingAreas.size() * 5;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003730 int32_t *focusingAreas = new int32_t[focusingAreasSize];
3731 for (size_t i = 0; i < focusingAreasSize; i += 5) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003732 focusingAreas[i + 0] = params.focusingAreas[i].left;
3733 focusingAreas[i + 1] = params.focusingAreas[i].top;
3734 focusingAreas[i + 2] = params.focusingAreas[i].right;
3735 focusingAreas[i + 3] = params.focusingAreas[i].bottom;
3736 focusingAreas[i + 4] = params.focusingAreas[i].weight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003737 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003738 res = request->update(ANDROID_CONTROL_AF_REGIONS,
3739 focusingAreas,focusingAreasSize);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003740 if (res != OK) return res;
3741 delete[] focusingAreas;
3742
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003743 res = request->update(ANDROID_CONTROL_AE_EXP_COMPENSATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003744 &params.exposureCompensation, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003745 if (res != OK) return res;
3746
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003747 size_t meteringAreasSize = params.meteringAreas.size() * 5;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003748 int32_t *meteringAreas = new int32_t[meteringAreasSize];
3749 for (size_t i = 0; i < meteringAreasSize; i += 5) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003750 meteringAreas[i + 0] = params.meteringAreas[i].left;
3751 meteringAreas[i + 1] = params.meteringAreas[i].top;
3752 meteringAreas[i + 2] = params.meteringAreas[i].right;
3753 meteringAreas[i + 3] = params.meteringAreas[i].bottom;
3754 meteringAreas[i + 4] = params.meteringAreas[i].weight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003755 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003756 res = request->update(ANDROID_CONTROL_AE_REGIONS,
3757 meteringAreas, meteringAreasSize);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003758 if (res != OK) return res;
3759
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003760 res = request->update(ANDROID_CONTROL_AWB_REGIONS,
3761 meteringAreas, meteringAreasSize);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003762 if (res != OK) return res;
3763 delete[] meteringAreas;
3764
3765 // Need to convert zoom index into a crop rectangle. The rectangle is
3766 // chosen to maximize its area on the sensor
3767
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003768 camera_metadata_ro_entry_t maxDigitalZoom =
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003769 staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM);
3770 float zoomIncrement = (maxDigitalZoom.data.f[0] - 1) /
3771 (NUM_ZOOM_STEPS-1);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003772 float zoomRatio = 1 + zoomIncrement * params.zoom;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003773
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003774 float zoomLeft, zoomTop, zoomWidth, zoomHeight;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003775 if (params.previewWidth >= params.previewHeight) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003776 zoomWidth = mDeviceInfo->arrayWidth / zoomRatio;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003777 zoomHeight = zoomWidth *
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003778 params.previewHeight / params.previewWidth;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003779 } else {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003780 zoomHeight = mDeviceInfo->arrayHeight / zoomRatio;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003781 zoomWidth = zoomHeight *
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003782 params.previewWidth / params.previewHeight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003783 }
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003784 zoomLeft = (mDeviceInfo->arrayWidth - zoomWidth) / 2;
3785 zoomTop = (mDeviceInfo->arrayHeight - zoomHeight) / 2;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003786
3787 int32_t cropRegion[3] = { zoomLeft, zoomTop, zoomWidth };
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003788 res = request->update(ANDROID_SCALER_CROP_REGION,
3789 cropRegion, 3);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003790 if (res != OK) return res;
3791
3792 // TODO: Decide how to map recordingHint, or whether just to ignore it
3793
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07003794 uint8_t vstabMode = params.videoStabilization ?
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003795 ANDROID_CONTROL_VIDEO_STABILIZATION_ON :
3796 ANDROID_CONTROL_VIDEO_STABILIZATION_OFF;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003797 res = request->update(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003798 &vstabMode, 1);
3799 if (res != OK) return res;
3800
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003801 uint8_t faceDetectMode = params.enableFaceDetect ?
3802 mDeviceInfo->bestFaceDetectMode :
3803 (uint8_t)ANDROID_STATS_FACE_DETECTION_OFF;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07003804 res = request->update(ANDROID_STATS_FACE_DETECT_MODE,
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003805 &faceDetectMode, 1);
3806 if (res != OK) return res;
3807
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07003808 return OK;
3809}
3810
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07003811int Camera2Client::arrayXToNormalized(int width) const {
3812 return width * 2000 / (mDeviceInfo->arrayWidth - 1) - 1000;
3813}
3814
3815int Camera2Client::arrayYToNormalized(int height) const {
3816 return height * 2000 / (mDeviceInfo->arrayHeight - 1) - 1000;
3817}
3818
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07003819int Camera2Client::formatStringToEnum(const char *format) {
3820 return
3821 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422SP) ?
3822 HAL_PIXEL_FORMAT_YCbCr_422_SP : // NV16
3823 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420SP) ?
3824 HAL_PIXEL_FORMAT_YCrCb_420_SP : // NV21
3825 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422I) ?
3826 HAL_PIXEL_FORMAT_YCbCr_422_I : // YUY2
3827 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420P) ?
3828 HAL_PIXEL_FORMAT_YV12 : // YV12
3829 !strcmp(format, CameraParameters::PIXEL_FORMAT_RGB565) ?
3830 HAL_PIXEL_FORMAT_RGB_565 : // RGB565
3831 !strcmp(format, CameraParameters::PIXEL_FORMAT_RGBA8888) ?
3832 HAL_PIXEL_FORMAT_RGBA_8888 : // RGB8888
3833 !strcmp(format, CameraParameters::PIXEL_FORMAT_BAYER_RGGB) ?
3834 HAL_PIXEL_FORMAT_RAW_SENSOR : // Raw sensor data
3835 -1;
3836}
3837
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07003838const char* Camera2Client::formatEnumToString(int format) {
3839 const char *fmt;
3840 switch(format) {
3841 case HAL_PIXEL_FORMAT_YCbCr_422_SP: // NV16
3842 fmt = CameraParameters::PIXEL_FORMAT_YUV422SP;
3843 break;
3844 case HAL_PIXEL_FORMAT_YCrCb_420_SP: // NV21
3845 fmt = CameraParameters::PIXEL_FORMAT_YUV420SP;
3846 break;
3847 case HAL_PIXEL_FORMAT_YCbCr_422_I: // YUY2
3848 fmt = CameraParameters::PIXEL_FORMAT_YUV422I;
3849 break;
3850 case HAL_PIXEL_FORMAT_YV12: // YV12
3851 fmt = CameraParameters::PIXEL_FORMAT_YUV420P;
3852 break;
3853 case HAL_PIXEL_FORMAT_RGB_565: // RGB565
3854 fmt = CameraParameters::PIXEL_FORMAT_RGB565;
3855 break;
3856 case HAL_PIXEL_FORMAT_RGBA_8888: // RGBA8888
3857 fmt = CameraParameters::PIXEL_FORMAT_RGBA8888;
3858 break;
3859 case HAL_PIXEL_FORMAT_RAW_SENSOR:
3860 ALOGW("Raw sensor preview format requested.");
3861 fmt = CameraParameters::PIXEL_FORMAT_BAYER_RGGB;
3862 break;
3863 default:
3864 ALOGE("%s: Unknown preview format: %x",
3865 __FUNCTION__, format);
3866 fmt = NULL;
3867 break;
3868 }
3869 return fmt;
3870}
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07003871
3872int Camera2Client::wbModeStringToEnum(const char *wbMode) {
3873 return
3874 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_AUTO) ?
3875 ANDROID_CONTROL_AWB_AUTO :
3876 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_INCANDESCENT) ?
3877 ANDROID_CONTROL_AWB_INCANDESCENT :
3878 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_FLUORESCENT) ?
3879 ANDROID_CONTROL_AWB_FLUORESCENT :
3880 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT) ?
3881 ANDROID_CONTROL_AWB_WARM_FLUORESCENT :
3882 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_DAYLIGHT) ?
3883 ANDROID_CONTROL_AWB_DAYLIGHT :
3884 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT) ?
3885 ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT :
3886 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_TWILIGHT) ?
3887 ANDROID_CONTROL_AWB_TWILIGHT :
3888 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_SHADE) ?
3889 ANDROID_CONTROL_AWB_SHADE :
3890 -1;
3891}
3892
3893int Camera2Client::effectModeStringToEnum(const char *effectMode) {
3894 return
3895 !strcmp(effectMode, CameraParameters::EFFECT_NONE) ?
3896 ANDROID_CONTROL_EFFECT_OFF :
3897 !strcmp(effectMode, CameraParameters::EFFECT_MONO) ?
3898 ANDROID_CONTROL_EFFECT_MONO :
3899 !strcmp(effectMode, CameraParameters::EFFECT_NEGATIVE) ?
3900 ANDROID_CONTROL_EFFECT_NEGATIVE :
3901 !strcmp(effectMode, CameraParameters::EFFECT_SOLARIZE) ?
3902 ANDROID_CONTROL_EFFECT_SOLARIZE :
3903 !strcmp(effectMode, CameraParameters::EFFECT_SEPIA) ?
3904 ANDROID_CONTROL_EFFECT_SEPIA :
3905 !strcmp(effectMode, CameraParameters::EFFECT_POSTERIZE) ?
3906 ANDROID_CONTROL_EFFECT_POSTERIZE :
3907 !strcmp(effectMode, CameraParameters::EFFECT_WHITEBOARD) ?
3908 ANDROID_CONTROL_EFFECT_WHITEBOARD :
3909 !strcmp(effectMode, CameraParameters::EFFECT_BLACKBOARD) ?
3910 ANDROID_CONTROL_EFFECT_BLACKBOARD :
3911 !strcmp(effectMode, CameraParameters::EFFECT_AQUA) ?
3912 ANDROID_CONTROL_EFFECT_AQUA :
3913 -1;
3914}
3915
3916int Camera2Client::abModeStringToEnum(const char *abMode) {
3917 return
3918 !strcmp(abMode, CameraParameters::ANTIBANDING_AUTO) ?
3919 ANDROID_CONTROL_AE_ANTIBANDING_AUTO :
3920 !strcmp(abMode, CameraParameters::ANTIBANDING_OFF) ?
3921 ANDROID_CONTROL_AE_ANTIBANDING_OFF :
3922 !strcmp(abMode, CameraParameters::ANTIBANDING_50HZ) ?
3923 ANDROID_CONTROL_AE_ANTIBANDING_50HZ :
3924 !strcmp(abMode, CameraParameters::ANTIBANDING_60HZ) ?
3925 ANDROID_CONTROL_AE_ANTIBANDING_60HZ :
3926 -1;
3927}
3928
3929int Camera2Client::sceneModeStringToEnum(const char *sceneMode) {
3930 return
3931 !strcmp(sceneMode, CameraParameters::SCENE_MODE_AUTO) ?
3932 ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED :
3933 !strcmp(sceneMode, CameraParameters::SCENE_MODE_ACTION) ?
3934 ANDROID_CONTROL_SCENE_MODE_ACTION :
3935 !strcmp(sceneMode, CameraParameters::SCENE_MODE_PORTRAIT) ?
3936 ANDROID_CONTROL_SCENE_MODE_PORTRAIT :
3937 !strcmp(sceneMode, CameraParameters::SCENE_MODE_LANDSCAPE) ?
3938 ANDROID_CONTROL_SCENE_MODE_LANDSCAPE :
3939 !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT) ?
3940 ANDROID_CONTROL_SCENE_MODE_NIGHT :
3941 !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT_PORTRAIT) ?
3942 ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT :
3943 !strcmp(sceneMode, CameraParameters::SCENE_MODE_THEATRE) ?
3944 ANDROID_CONTROL_SCENE_MODE_THEATRE :
3945 !strcmp(sceneMode, CameraParameters::SCENE_MODE_BEACH) ?
3946 ANDROID_CONTROL_SCENE_MODE_BEACH :
3947 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SNOW) ?
3948 ANDROID_CONTROL_SCENE_MODE_SNOW :
3949 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SUNSET) ?
3950 ANDROID_CONTROL_SCENE_MODE_SUNSET :
3951 !strcmp(sceneMode, CameraParameters::SCENE_MODE_STEADYPHOTO) ?
3952 ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO :
3953 !strcmp(sceneMode, CameraParameters::SCENE_MODE_FIREWORKS) ?
3954 ANDROID_CONTROL_SCENE_MODE_FIREWORKS :
3955 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SPORTS) ?
3956 ANDROID_CONTROL_SCENE_MODE_SPORTS :
3957 !strcmp(sceneMode, CameraParameters::SCENE_MODE_PARTY) ?
3958 ANDROID_CONTROL_SCENE_MODE_PARTY :
3959 !strcmp(sceneMode, CameraParameters::SCENE_MODE_CANDLELIGHT) ?
3960 ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT :
3961 !strcmp(sceneMode, CameraParameters::SCENE_MODE_BARCODE) ?
3962 ANDROID_CONTROL_SCENE_MODE_BARCODE:
3963 -1;
3964}
3965
3966Camera2Client::Parameters::flashMode_t Camera2Client::flashModeStringToEnum(
3967 const char *flashMode) {
3968 return
3969 !strcmp(flashMode, CameraParameters::FLASH_MODE_OFF) ?
3970 Parameters::FLASH_MODE_OFF :
3971 !strcmp(flashMode, CameraParameters::FLASH_MODE_AUTO) ?
3972 Parameters::FLASH_MODE_AUTO :
3973 !strcmp(flashMode, CameraParameters::FLASH_MODE_ON) ?
3974 Parameters::FLASH_MODE_ON :
3975 !strcmp(flashMode, CameraParameters::FLASH_MODE_RED_EYE) ?
3976 Parameters::FLASH_MODE_RED_EYE :
3977 !strcmp(flashMode, CameraParameters::FLASH_MODE_TORCH) ?
3978 Parameters::FLASH_MODE_TORCH :
3979 Parameters::FLASH_MODE_INVALID;
3980}
3981
3982Camera2Client::Parameters::focusMode_t Camera2Client::focusModeStringToEnum(
3983 const char *focusMode) {
3984 return
3985 !strcmp(focusMode, CameraParameters::FOCUS_MODE_AUTO) ?
3986 Parameters::FOCUS_MODE_AUTO :
3987 !strcmp(focusMode, CameraParameters::FOCUS_MODE_INFINITY) ?
3988 Parameters::FOCUS_MODE_INFINITY :
3989 !strcmp(focusMode, CameraParameters::FOCUS_MODE_MACRO) ?
3990 Parameters::FOCUS_MODE_MACRO :
3991 !strcmp(focusMode, CameraParameters::FOCUS_MODE_FIXED) ?
3992 Parameters::FOCUS_MODE_FIXED :
3993 !strcmp(focusMode, CameraParameters::FOCUS_MODE_EDOF) ?
3994 Parameters::FOCUS_MODE_EDOF :
3995 !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO) ?
3996 Parameters::FOCUS_MODE_CONTINUOUS_VIDEO :
3997 !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE) ?
3998 Parameters::FOCUS_MODE_CONTINUOUS_PICTURE :
3999 Parameters::FOCUS_MODE_INVALID;
4000}
4001
4002status_t Camera2Client::parseAreas(const char *areasCStr,
4003 Vector<Parameters::Area> *areas) {
4004 static const size_t NUM_FIELDS = 5;
4005 areas->clear();
4006 if (areasCStr == NULL) {
4007 // If no key exists, use default (0,0,0,0,0)
4008 areas->push();
4009 return OK;
4010 }
4011 String8 areasStr(areasCStr);
4012 ssize_t areaStart = areasStr.find("(", 0) + 1;
4013 while (areaStart != 0) {
4014 const char* area = areasStr.string() + areaStart;
4015 char *numEnd;
4016 int vals[NUM_FIELDS];
4017 for (size_t i = 0; i < NUM_FIELDS; i++) {
4018 errno = 0;
4019 vals[i] = strtol(area, &numEnd, 10);
4020 if (errno || numEnd == area) return BAD_VALUE;
4021 area = numEnd + 1;
4022 }
4023 areas->push(Parameters::Area(
4024 vals[0], vals[1], vals[2], vals[3], vals[4]) );
4025 areaStart = areasStr.find("(", areaStart) + 1;
4026 }
4027 return OK;
4028}
4029
4030status_t Camera2Client::validateAreas(const Vector<Parameters::Area> &areas,
4031 size_t maxRegions) {
4032 // Definition of valid area can be found in
4033 // include/camera/CameraParameters.h
4034 if (areas.size() == 0) return BAD_VALUE;
4035 if (areas.size() == 1) {
4036 if (areas[0].left == 0 &&
4037 areas[0].top == 0 &&
4038 areas[0].right == 0 &&
4039 areas[0].bottom == 0 &&
4040 areas[0].weight == 0) {
4041 // Single (0,0,0,0,0) entry is always valid (== driver decides)
4042 return OK;
4043 }
4044 }
4045 if (areas.size() > maxRegions) {
4046 ALOGE("%s: Too many areas requested: %d",
4047 __FUNCTION__, areas.size());
4048 return BAD_VALUE;
4049 }
4050
4051 for (Vector<Parameters::Area>::const_iterator a = areas.begin();
4052 a != areas.end(); a++) {
4053 if (a->weight < 1 || a->weight > 1000) return BAD_VALUE;
4054 if (a->left < -1000 || a->left > 1000) return BAD_VALUE;
4055 if (a->top < -1000 || a->top > 1000) return BAD_VALUE;
4056 if (a->right < -1000 || a->right > 1000) return BAD_VALUE;
4057 if (a->bottom < -1000 || a->bottom > 1000) return BAD_VALUE;
4058 if (a->left >= a->right) return BAD_VALUE;
4059 if (a->top >= a->bottom) return BAD_VALUE;
4060 }
4061 return OK;
4062}
4063
4064bool Camera2Client::boolFromString(const char *boolStr) {
4065 return !boolStr ? false :
4066 !strcmp(boolStr, CameraParameters::TRUE) ? true :
4067 false;
4068}
4069
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07004070int Camera2Client::degToTransform(int degrees, bool mirror) {
4071 if (!mirror) {
4072 if (degrees == 0) return 0;
4073 else if (degrees == 90) return HAL_TRANSFORM_ROT_90;
4074 else if (degrees == 180) return HAL_TRANSFORM_ROT_180;
4075 else if (degrees == 270) return HAL_TRANSFORM_ROT_270;
4076 } else { // Do mirror (horizontal flip)
4077 if (degrees == 0) { // FLIP_H and ROT_0
4078 return HAL_TRANSFORM_FLIP_H;
4079 } else if (degrees == 90) { // FLIP_H and ROT_90
4080 return HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90;
4081 } else if (degrees == 180) { // FLIP_H and ROT_180
4082 return HAL_TRANSFORM_FLIP_V;
4083 } else if (degrees == 270) { // FLIP_H and ROT_270
4084 return HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90;
4085 }
4086 }
4087 ALOGE("%s: Bad input: %d", __FUNCTION__, degrees);
4088 return -1;
4089}
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07004090
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07004091size_t Camera2Client::calculateBufferSize(int width, int height,
4092 int format, int stride) {
4093 switch (format) {
4094 case HAL_PIXEL_FORMAT_YCbCr_422_SP: // NV16
4095 return width * height * 2;
4096 case HAL_PIXEL_FORMAT_YCrCb_420_SP: // NV21
4097 return width * height * 3 / 2;
4098 case HAL_PIXEL_FORMAT_YCbCr_422_I: // YUY2
4099 return width * height * 2;
4100 case HAL_PIXEL_FORMAT_YV12: { // YV12
4101 size_t ySize = stride * height;
4102 size_t uvStride = (stride / 2 + 0xF) & ~0x10;
4103 size_t uvSize = uvStride * height / 2;
4104 return ySize + uvSize * 2;
4105 }
4106 case HAL_PIXEL_FORMAT_RGB_565:
4107 return width * height * 2;
4108 case HAL_PIXEL_FORMAT_RGBA_8888:
4109 return width * height * 4;
4110 case HAL_PIXEL_FORMAT_RAW_SENSOR:
4111 return width * height * 2;
4112 default:
4113 ALOGE("%s: Unknown preview format: %x",
4114 __FUNCTION__, format);
4115 return 0;
4116 }
4117}
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07004118
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07004119} // namespace android