blob: 62741d56be00c385fe2b7a617630a72ebab0e18d [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 Talvala6db981c2012-05-21 18:54:30 -070055 mState(NOT_INITIALIZED),
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -070056 mPreviewStreamId(NO_STREAM),
57 mPreviewRequest(NULL),
58 mCaptureStreamId(NO_STREAM),
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -070059 mCaptureRequest(NULL),
60 mRecordingStreamId(NO_STREAM),
61 mRecordingRequest(NULL)
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070062{
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070063 ATRACE_CALL();
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070064
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070065 mDevice = new Camera2Device(cameraId);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070066}
67
68status_t Camera2Client::initialize(camera_module_t *module)
69{
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070070 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -070071 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070072 status_t res;
73
74 res = mDevice->initialize(module);
75 if (res != OK) {
76 ALOGE("%s: Camera %d: unable to initialize device: %s (%d)",
77 __FUNCTION__, mCameraId, strerror(-res), res);
78 return NO_INIT;
79 }
80
81 res = buildDefaultParameters();
82 if (res != OK) {
83 ALOGE("%s: Camera %d: unable to build defaults: %s (%d)",
84 __FUNCTION__, mCameraId, strerror(-res), res);
85 return NO_INIT;
86 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -070087
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070088 if (gLogLevel >= 1) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -070089 LockedParameters::Key k(mParameters);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070090 ALOGD("%s: Default parameters converted from camera %d:", __FUNCTION__,
91 mCameraId);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -070092 ALOGD("%s", k.mParameters.paramsFlattened.string());
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070093 }
94
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -070095 mState = STOPPED;
96
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070097 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070098}
99
100Camera2Client::~Camera2Client() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700101 ATRACE_CALL();
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700102 ALOGV("%s: Camera %d: Shutting down", __FUNCTION__, mCameraId);
103
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700104 mDestructionStarted = true;
105
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700106 disconnect();
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -0700107
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700108}
109
110status_t Camera2Client::dump(int fd, const Vector<String16>& args) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700111 String8 result;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700112 result.appendFormat("Client2[%d] (%p) PID: %d, dump:\n",
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700113 mCameraId,
114 getCameraClient()->asBinder().get(),
115 mClientPid);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700116 result.append(" State: ");
117#define CASE_APPEND_ENUM(x) case x: result.append(#x "\n"); break;
118
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700119 const Parameters& p = mParameters.unsafeUnlock();
120
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700121 result.append(getStateName(mState));
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700122
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700123 result.append("\n Current parameters:\n");
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700124 result.appendFormat(" Preview size: %d x %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700125 p.previewWidth, p.previewHeight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700126 result.appendFormat(" Preview FPS range: %d - %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700127 p.previewFpsRange[0], p.previewFpsRange[1]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700128 result.appendFormat(" Preview HAL pixel format: 0x%x\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700129 p.previewFormat);
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700130 result.appendFormat(" Preview transform: %x\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700131 p.previewTransform);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700132 result.appendFormat(" Picture size: %d x %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700133 p.pictureWidth, p.pictureHeight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700134 result.appendFormat(" Jpeg thumbnail size: %d x %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700135 p.jpegThumbSize[0], p.jpegThumbSize[1]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700136 result.appendFormat(" Jpeg quality: %d, thumbnail quality: %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700137 p.jpegQuality, p.jpegThumbQuality);
138 result.appendFormat(" Jpeg rotation: %d\n", p.jpegRotation);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700139 result.appendFormat(" GPS tags %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700140 p.gpsEnabled ? "enabled" : "disabled");
141 if (p.gpsEnabled) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700142 result.appendFormat(" GPS lat x long x alt: %f x %f x %f\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700143 p.gpsCoordinates[0], p.gpsCoordinates[1],
144 p.gpsCoordinates[2]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700145 result.appendFormat(" GPS timestamp: %lld\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700146 p.gpsTimestamp);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700147 result.appendFormat(" GPS processing method: %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700148 p.gpsProcessingMethod.string());
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700149 }
150
151 result.append(" White balance mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700152 switch (p.wbMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700153 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_AUTO)
154 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_INCANDESCENT)
155 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_FLUORESCENT)
156 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_WARM_FLUORESCENT)
157 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_DAYLIGHT)
158 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT)
159 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_TWILIGHT)
160 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_SHADE)
161 default: result.append("UNKNOWN\n");
162 }
163
164 result.append(" Effect mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700165 switch (p.effectMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700166 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_OFF)
167 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_MONO)
168 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_NEGATIVE)
169 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_SOLARIZE)
170 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_SEPIA)
171 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_POSTERIZE)
172 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_WHITEBOARD)
173 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_BLACKBOARD)
174 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_AQUA)
175 default: result.append("UNKNOWN\n");
176 }
177
178 result.append(" Antibanding mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700179 switch (p.antibandingMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700180 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_AUTO)
181 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_OFF)
182 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_50HZ)
183 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_60HZ)
184 default: result.append("UNKNOWN\n");
185 }
186
187 result.append(" Scene mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700188 switch (p.sceneMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700189 case ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED:
190 result.append("AUTO\n"); break;
191 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_ACTION)
192 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_PORTRAIT)
193 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_LANDSCAPE)
194 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_NIGHT)
195 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT)
196 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_THEATRE)
197 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_BEACH)
198 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SNOW)
199 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SUNSET)
200 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO)
201 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_FIREWORKS)
202 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SPORTS)
203 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_PARTY)
204 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT)
205 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_BARCODE)
206 default: result.append("UNKNOWN\n");
207 }
208
209 result.append(" Flash mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700210 switch (p.flashMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700211 CASE_APPEND_ENUM(Parameters::FLASH_MODE_OFF)
212 CASE_APPEND_ENUM(Parameters::FLASH_MODE_AUTO)
213 CASE_APPEND_ENUM(Parameters::FLASH_MODE_ON)
214 CASE_APPEND_ENUM(Parameters::FLASH_MODE_TORCH)
215 CASE_APPEND_ENUM(Parameters::FLASH_MODE_RED_EYE)
216 CASE_APPEND_ENUM(Parameters::FLASH_MODE_INVALID)
217 default: result.append("UNKNOWN\n");
218 }
219
220 result.append(" Focus mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700221 switch (p.focusMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700222 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_AUTO)
223 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_MACRO)
224 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_CONTINUOUS_VIDEO)
225 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_CONTINUOUS_PICTURE)
226 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_EDOF)
227 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_INFINITY)
228 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_FIXED)
229 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_INVALID)
230 default: result.append("UNKNOWN\n");
231 }
232
233 result.append(" Focusing areas:\n");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700234 for (size_t i = 0; i < p.focusingAreas.size(); i++) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700235 result.appendFormat(" [ (%d, %d, %d, %d), weight %d ]\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700236 p.focusingAreas[i].left,
237 p.focusingAreas[i].top,
238 p.focusingAreas[i].right,
239 p.focusingAreas[i].bottom,
240 p.focusingAreas[i].weight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700241 }
242
243 result.appendFormat(" Exposure compensation index: %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700244 p.exposureCompensation);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700245
246 result.appendFormat(" AE lock %s, AWB lock %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700247 p.autoExposureLock ? "enabled" : "disabled",
248 p.autoWhiteBalanceLock ? "enabled" : "disabled" );
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700249
250 result.appendFormat(" Metering areas:\n");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700251 for (size_t i = 0; i < p.meteringAreas.size(); i++) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700252 result.appendFormat(" [ (%d, %d, %d, %d), weight %d ]\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700253 p.meteringAreas[i].left,
254 p.meteringAreas[i].top,
255 p.meteringAreas[i].right,
256 p.meteringAreas[i].bottom,
257 p.meteringAreas[i].weight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700258 }
259
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700260 result.appendFormat(" Zoom index: %d\n", p.zoom);
261 result.appendFormat(" Video size: %d x %d\n", p.videoWidth,
262 p.videoHeight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700263
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700264 result.appendFormat(" Recording hint is %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700265 p.recordingHint ? "set" : "not set");
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700266
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700267 result.appendFormat(" Video stabilization is %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700268 p.videoStabilization ? "enabled" : "disabled");
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700269
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700270 result.append(" Current streams:\n");
271 result.appendFormat(" Preview stream ID: %d\n", mPreviewStreamId);
272 result.appendFormat(" Capture stream ID: %d\n", mCaptureStreamId);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700273 result.appendFormat(" Recording stream ID: %d\n", mRecordingStreamId);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700274
275 result.append(" Current requests:\n");
276 if (mPreviewRequest != NULL) {
277 result.append(" Preview request:\n");
278 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700279 dump_indented_camera_metadata(mPreviewRequest, fd, 2, 6);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700280 } else {
281 result.append(" Preview request: undefined\n");
282 write(fd, result.string(), result.size());
283 }
284
285 if (mCaptureRequest != NULL) {
286 result = " Capture request:\n";
287 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700288 dump_indented_camera_metadata(mCaptureRequest, fd, 2, 6);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700289 } else {
290 result = " Capture request: undefined\n";
291 write(fd, result.string(), result.size());
292 }
293
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700294 if (mRecordingRequest != NULL) {
295 result = " Recording request:\n";
296 write(fd, result.string(), result.size());
297 dump_indented_camera_metadata(mRecordingRequest, fd, 2, 6);
298 } else {
299 result = " Recording request: undefined\n";
300 write(fd, result.string(), result.size());
301 }
302
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700303 result = " Device dump:\n";
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700304 write(fd, result.string(), result.size());
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700305
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700306 status_t res = mDevice->dump(fd, args);
307 if (res != OK) {
308 result = String8::format(" Error dumping device: %s (%d)",
309 strerror(-res), res);
310 write(fd, result.string(), result.size());
311 }
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700312
313#undef CASE_APPEND_ENUM
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700314 return NO_ERROR;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700315}
316
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700317const char* Camera2Client::getStateName(State state) {
318#define CASE_ENUM_TO_CHAR(x) case x: return(#x); break;
319 switch(state) {
320 CASE_ENUM_TO_CHAR(NOT_INITIALIZED)
321 CASE_ENUM_TO_CHAR(STOPPED)
322 CASE_ENUM_TO_CHAR(WAITING_FOR_PREVIEW_WINDOW)
323 CASE_ENUM_TO_CHAR(PREVIEW)
324 CASE_ENUM_TO_CHAR(RECORD)
325 CASE_ENUM_TO_CHAR(STILL_CAPTURE)
326 CASE_ENUM_TO_CHAR(VIDEO_SNAPSHOT)
327 default:
328 return "Unknown state!";
329 break;
330 }
331#undef CASE_ENUM_TO_CHAR
332}
333
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700334// ICamera interface
335
336void Camera2Client::disconnect() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700337 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700338 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700339 Mutex::Autolock icl(mICameraLock);
340
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700341 if (mDevice == 0) return;
342
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700343 stopPreviewLocked();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700344
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700345 mDevice->waitUntilDrained();
346
347 if (mPreviewStreamId != NO_STREAM) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700348 mDevice->deleteStream(mPreviewStreamId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700349 mPreviewStreamId = NO_STREAM;
350 }
351
352 if (mCaptureStreamId != NO_STREAM) {
353 mDevice->deleteStream(mCaptureStreamId);
354 mCaptureStreamId = NO_STREAM;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700355 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700356
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -0700357 if (mRecordingStreamId != NO_STREAM) {
358 mDevice->deleteStream(mRecordingStreamId);
359 mRecordingStreamId = NO_STREAM;
360 }
361
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700362 CameraService::Client::disconnect();
363}
364
365status_t Camera2Client::connect(const sp<ICameraClient>& client) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700366 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700367 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700368 Mutex::Autolock icl(mICameraLock);
369
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700370 if (mClientPid != 0 && getCallingPid() != mClientPid) {
371 ALOGE("%s: Camera %d: Connection attempt from pid %d; "
372 "current locked to pid %d", __FUNCTION__,
373 mCameraId, getCallingPid(), mClientPid);
374 return BAD_VALUE;
375 }
376
377 mClientPid = getCallingPid();
378 mCameraClient = client;
379
380 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700381}
382
383status_t Camera2Client::lock() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700384 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700385 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700386 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700387 ALOGV("%s: Camera %d: Lock call from pid %d; current client pid %d",
388 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700389
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700390 if (mClientPid == 0) {
391 mClientPid = getCallingPid();
392 return OK;
393 }
394
395 if (mClientPid != getCallingPid()) {
396 ALOGE("%s: Camera %d: Lock call from pid %d; currently locked to pid %d",
397 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
398 return EBUSY;
399 }
400
401 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700402}
403
404status_t Camera2Client::unlock() {
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);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700408 ALOGV("%s: Camera %d: Unlock call from pid %d; current client pid %d",
409 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700410
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700411 // TODO: Check for uninterruptable conditions
412
413 if (mClientPid == getCallingPid()) {
414 mClientPid = 0;
415 mCameraClient.clear();
416 return OK;
417 }
418
419 ALOGE("%s: Camera %d: Unlock call from pid %d; currently locked to pid %d",
420 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
421 return EBUSY;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700422}
423
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700424status_t Camera2Client::setPreviewDisplay(
425 const sp<Surface>& surface) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700426 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700427 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700428 Mutex::Autolock icl(mICameraLock);
429
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700430 sp<IBinder> binder;
431 sp<ANativeWindow> window;
432 if (surface != 0) {
433 binder = surface->asBinder();
434 window = surface;
435 }
436
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700437 return setPreviewWindowLocked(binder,window);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700438}
439
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700440status_t Camera2Client::setPreviewTexture(
441 const sp<ISurfaceTexture>& surfaceTexture) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700442 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700443 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700444 Mutex::Autolock icl(mICameraLock);
445
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700446 sp<IBinder> binder;
447 sp<ANativeWindow> window;
448 if (surfaceTexture != 0) {
449 binder = surfaceTexture->asBinder();
450 window = new SurfaceTextureClient(surfaceTexture);
451 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700452 return setPreviewWindowLocked(binder, window);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700453}
454
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700455status_t Camera2Client::setPreviewWindowLocked(const sp<IBinder>& binder,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700456 sp<ANativeWindow> window) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700457 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700458 status_t res;
459
460 if (binder == mPreviewSurface) {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700461 ALOGV("%s: Camera %d: New window is same as old window",
462 __FUNCTION__, mCameraId);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700463 return NO_ERROR;
464 }
465
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700466 switch (mState) {
467 case NOT_INITIALIZED:
468 case RECORD:
469 case STILL_CAPTURE:
470 case VIDEO_SNAPSHOT:
471 ALOGE("%s: Camera %d: Cannot set preview display while in state %s",
472 __FUNCTION__, mCameraId, getStateName(mState));
473 return INVALID_OPERATION;
474 case STOPPED:
475 case WAITING_FOR_PREVIEW_WINDOW:
476 // OK
477 break;
478 case PREVIEW:
479 // Already running preview - need to stop and create a new stream
480 // TODO: Optimize this so that we don't wait for old stream to drain
481 // before spinning up new stream
482 mDevice->setStreamingRequest(NULL);
483 mState = WAITING_FOR_PREVIEW_WINDOW;
484 break;
485 }
486
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700487 if (mPreviewStreamId != NO_STREAM) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700488 res = mDevice->waitUntilDrained();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700489 if (res != OK) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700490 ALOGE("%s: Error waiting for preview to drain: %s (%d)",
491 __FUNCTION__, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700492 return res;
493 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700494 res = mDevice->deleteStream(mPreviewStreamId);
495 if (res != OK) {
496 ALOGE("%s: Unable to delete old preview stream: %s (%d)",
497 __FUNCTION__, strerror(-res), res);
498 return res;
499 }
500 mPreviewStreamId = NO_STREAM;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700501 }
502
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700503 mPreviewSurface = binder;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700504 mPreviewWindow = window;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700505
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700506 if (mState == WAITING_FOR_PREVIEW_WINDOW) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700507 return startPreviewLocked();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700508 }
509
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700510 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700511}
512
513void Camera2Client::setPreviewCallbackFlag(int flag) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700514 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700515 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700516}
517
518status_t Camera2Client::startPreview() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700519 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700520 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700521 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700522 return startPreviewLocked();
523}
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700524
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700525status_t Camera2Client::startPreviewLocked() {
526 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700527 status_t res;
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700528 if (mState >= PREVIEW) {
529 ALOGE("%s: Can't start preview in state %s",
530 __FUNCTION__, getStateName(mState));
531 return INVALID_OPERATION;
532 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700533
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700534 if (mPreviewWindow == 0) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700535 mState = WAITING_FOR_PREVIEW_WINDOW;
536 return OK;
537 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700538 mState = STOPPED;
539
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700540 LockedParameters::Key k(mParameters);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700541
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700542 res = updatePreviewStream(k.mParameters);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700543 if (res != OK) {
544 ALOGE("%s: Camera %d: Unable to update preview stream: %s (%d)",
545 __FUNCTION__, mCameraId, strerror(-res), res);
546 return res;
547 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700548
549 if (mPreviewRequest == NULL) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700550 res = updatePreviewRequest(k.mParameters);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700551 if (res != OK) {
552 ALOGE("%s: Camera %d: Unable to create preview request: %s (%d)",
553 __FUNCTION__, mCameraId, strerror(-res), res);
554 return res;
555 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700556 }
557
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700558 res = updateEntry(mPreviewRequest,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700559 ANDROID_REQUEST_OUTPUT_STREAMS,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700560 &mPreviewStreamId, 1);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700561 if (res != OK) {
562 ALOGE("%s: Camera %d: Unable to set up preview request: %s (%d)",
563 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700564 return res;
565 }
566 res = sort_camera_metadata(mPreviewRequest);
567 if (res != OK) {
568 ALOGE("%s: Camera %d: Error sorting preview request: %s (%d)",
569 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700570 return res;
571 }
572
573 res = mDevice->setStreamingRequest(mPreviewRequest);
574 if (res != OK) {
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700575 ALOGE("%s: Camera %d: Unable to set preview request to start preview: "
576 "%s (%d)",
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700577 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700578 return res;
579 }
580 mState = PREVIEW;
581
582 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700583}
584
585void Camera2Client::stopPreview() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700586 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700587 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700588 Mutex::Autolock icl(mICameraLock);
589 stopPreviewLocked();
590}
591
592void Camera2Client::stopPreviewLocked() {
593 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700594 switch (mState) {
595 case NOT_INITIALIZED:
596 ALOGE("%s: Camera %d: Call before initialized",
597 __FUNCTION__, mCameraId);
598 break;
599 case STOPPED:
600 break;
601 case STILL_CAPTURE:
602 ALOGE("%s: Camera %d: Cannot stop preview during still capture.",
603 __FUNCTION__, mCameraId);
604 break;
605 case RECORD:
606 // TODO: Handle record stop here
607 case PREVIEW:
608 mDevice->setStreamingRequest(NULL);
Eino-Ville Talvala22671062012-07-20 18:30:37 -0700609 mDevice->waitUntilDrained();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700610 case WAITING_FOR_PREVIEW_WINDOW:
611 mState = STOPPED;
612 break;
613 default:
614 ALOGE("%s: Camera %d: Unknown state %d", __FUNCTION__, mCameraId,
615 mState);
616 }
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700617}
618
619bool Camera2Client::previewEnabled() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700620 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700621 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700622 return mState == PREVIEW;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700623}
624
625status_t Camera2Client::storeMetaDataInBuffers(bool enabled) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700626 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700627 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700628 switch (mState) {
629 case RECORD:
630 case VIDEO_SNAPSHOT:
631 ALOGE("%s: Camera %d: Can't be called in state %s",
632 __FUNCTION__, mCameraId, getStateName(mState));
633 return INVALID_OPERATION;
634 default:
635 // OK
636 break;
637 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700638 LockedParameters::Key k(mParameters);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700639
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700640 k.mParameters.storeMetadataInBuffers = enabled;
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700641
642 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700643}
644
645status_t Camera2Client::startRecording() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700646 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700647 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700648 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700649 status_t res;
650 switch (mState) {
651 case STOPPED:
652 res = startPreviewLocked();
653 if (res != OK) return res;
654 break;
655 case PREVIEW:
656 // Ready to go
657 break;
658 case RECORD:
659 case VIDEO_SNAPSHOT:
660 // OK to call this when recording is already on
661 return OK;
662 break;
663 default:
664 ALOGE("%s: Camera %d: Can't start recording in state %s",
665 __FUNCTION__, mCameraId, getStateName(mState));
666 return INVALID_OPERATION;
667 };
668
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700669 LockedParameters::Key k(mParameters);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700670
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700671 if (!k.mParameters.storeMetadataInBuffers) {
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700672 ALOGE("%s: Camera %d: Recording only supported in metadata mode, but "
673 "non-metadata recording mode requested!", __FUNCTION__,
674 mCameraId);
675 return INVALID_OPERATION;
676 }
677
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700678 res = updateRecordingStream(k.mParameters);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700679 if (res != OK) {
680 ALOGE("%s: Camera %d: Unable to update recording stream: %s (%d)",
681 __FUNCTION__, mCameraId, strerror(-res), res);
682 return res;
683 }
684
685 if (mRecordingRequest == NULL) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700686 res = updateRecordingRequest(k.mParameters);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700687 if (res != OK) {
688 ALOGE("%s: Camera %d: Unable to create recording request: %s (%d)",
689 __FUNCTION__, mCameraId, strerror(-res), res);
690 return res;
691 }
692 }
693
694 uint8_t outputStreams[2] = { mPreviewStreamId, mRecordingStreamId };
695 res = updateEntry(mRecordingRequest,
696 ANDROID_REQUEST_OUTPUT_STREAMS,
697 outputStreams, 2);
698 if (res != OK) {
699 ALOGE("%s: Camera %d: Unable to set up recording request: %s (%d)",
700 __FUNCTION__, mCameraId, strerror(-res), res);
701 return res;
702 }
703 res = sort_camera_metadata(mRecordingRequest);
704 if (res != OK) {
705 ALOGE("%s: Camera %d: Error sorting recording request: %s (%d)",
706 __FUNCTION__, mCameraId, strerror(-res), res);
707 return res;
708 }
709
710 res = mDevice->setStreamingRequest(mRecordingRequest);
711 if (res != OK) {
712 ALOGE("%s: Camera %d: Unable to set recording request to start "
713 "recording: %s (%d)", __FUNCTION__, mCameraId,
714 strerror(-res), res);
715 return res;
716 }
717 mState = RECORD;
718
719 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700720}
721
722void Camera2Client::stopRecording() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700723 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700724 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700725 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700726 status_t res;
727 switch (mState) {
728 case RECORD:
729 // OK to stop
730 break;
731 case STOPPED:
732 case PREVIEW:
733 case STILL_CAPTURE:
734 case VIDEO_SNAPSHOT:
735 default:
736 ALOGE("%s: Camera %d: Can't stop recording in state %s",
737 __FUNCTION__, mCameraId, getStateName(mState));
738 return;
739 };
740
741 // Back to preview. Since record can only be reached through preview,
742 // all preview stream setup should be up to date.
743 res = mDevice->setStreamingRequest(mPreviewRequest);
744 if (res != OK) {
745 ALOGE("%s: Camera %d: Unable to switch back to preview request: "
746 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
747 return;
748 }
749
750 // TODO: Should recording heap be freed? Can't do it yet since requests
751 // could still be in flight.
752
753 mState = PREVIEW;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700754}
755
756bool Camera2Client::recordingEnabled() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700757 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700758 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700759 return (mState == RECORD || mState == VIDEO_SNAPSHOT);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700760}
761
762void Camera2Client::releaseRecordingFrame(const sp<IMemory>& mem) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700763 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700764 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700765 // Make sure this is for the current heap
766 ssize_t offset;
767 size_t size;
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700768 status_t res;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700769 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
770 if (heap->getHeapID() != mRecordingHeap->mHeap->getHeapID()) {
771 ALOGW("%s: Camera %d: Mismatched heap ID, ignoring release "
772 "(got %x, expected %x)", __FUNCTION__, mCameraId,
773 heap->getHeapID(), mRecordingHeap->mHeap->getHeapID());
774 return;
775 }
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700776 uint8_t *data = (uint8_t*)heap->getBase() + offset;
777 uint32_t type = *(uint32_t*)data;
778 if (type != kMetadataBufferTypeGrallocSource) {
779 ALOGE("%s: Camera %d: Recording frame type invalid (got %x, expected %x)",
780 __FUNCTION__, mCameraId, type, kMetadataBufferTypeGrallocSource);
781 return;
782 }
783 buffer_handle_t imgBuffer = *(buffer_handle_t*)(data + 4);
784 ALOGV("%s: Camera %d: Freeing buffer_handle_t %p", __FUNCTION__, mCameraId,
Eino-Ville Talvala803cbf62012-07-25 15:23:36 -0700785 imgBuffer);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700786 res = mRecordingConsumer->freeBuffer(imgBuffer);
787 if (res != OK) {
788 ALOGE("%s: Camera %d: Unable to free recording frame (buffer_handle_t: %p):"
789 "%s (%d)",
790 __FUNCTION__, mCameraId, imgBuffer, strerror(-res), res);
791 return;
792 }
793
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700794 mRecordingHeapFree++;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700795}
796
797status_t Camera2Client::autoFocus() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700798 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700799 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700800 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700801}
802
803status_t Camera2Client::cancelAutoFocus() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700804 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700805 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700806 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700807}
808
809status_t Camera2Client::takePicture(int msgType) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700810 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700811 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700812 status_t res;
813
814 switch (mState) {
815 case NOT_INITIALIZED:
816 case STOPPED:
817 case WAITING_FOR_PREVIEW_WINDOW:
818 ALOGE("%s: Camera %d: Cannot take picture without preview enabled",
819 __FUNCTION__, mCameraId);
820 return INVALID_OPERATION;
821 case PREVIEW:
822 case RECORD:
823 // Good to go for takePicture
824 break;
825 case STILL_CAPTURE:
826 case VIDEO_SNAPSHOT:
827 ALOGE("%s: Camera %d: Already taking a picture",
828 __FUNCTION__, mCameraId);
829 return INVALID_OPERATION;
830 }
831
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700832 LockedParameters::Key k(mParameters);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700833
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700834 res = updateCaptureStream(k.mParameters);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700835 if (res != OK) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700836 ALOGE("%s: Camera %d: Can't set up still image stream: %s (%d)",
837 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700838 return res;
839 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700840
841 if (mCaptureRequest == NULL) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700842 res = updateCaptureRequest(k.mParameters);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700843 if (res != OK) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700844 ALOGE("%s: Camera %d: Can't create still image capture request: "
845 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700846 return res;
847 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700848 }
849
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700850 camera_metadata_entry_t outputStreams;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700851 if (mState == PREVIEW) {
852 uint8_t streamIds[2] = { mPreviewStreamId, mCaptureStreamId };
853 res = updateEntry(mCaptureRequest, ANDROID_REQUEST_OUTPUT_STREAMS,
854 &streamIds, 2);
855 } else if (mState == RECORD) {
856 uint8_t streamIds[3] = { mPreviewStreamId, mRecordingStreamId,
857 mCaptureStreamId };
858 res = updateEntry(mCaptureRequest, ANDROID_REQUEST_OUTPUT_STREAMS,
859 &streamIds, 3);
860 }
861
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700862 if (res != OK) {
863 ALOGE("%s: Camera %d: Unable to set up still image capture request: "
864 "%s (%d)",
865 __FUNCTION__, mCameraId, strerror(-res), res);
866 return res;
867 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700868 res = sort_camera_metadata(mCaptureRequest);
869 if (res != OK) {
870 ALOGE("%s: Camera %d: Unable to sort capture request: %s (%d)",
871 __FUNCTION__, mCameraId, strerror(-res), res);
872 return res;
873 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700874
875 camera_metadata_t *captureCopy = clone_camera_metadata(mCaptureRequest);
876 if (captureCopy == NULL) {
877 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device",
878 __FUNCTION__, mCameraId);
879 return NO_MEMORY;
880 }
881
882 if (mState == PREVIEW) {
883 res = mDevice->setStreamingRequest(NULL);
884 if (res != OK) {
885 ALOGE("%s: Camera %d: Unable to stop preview for still capture: "
886 "%s (%d)",
887 __FUNCTION__, mCameraId, strerror(-res), res);
888 return res;
889 }
890 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700891 // TODO: Capture should be atomic with setStreamingRequest here
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700892 res = mDevice->capture(captureCopy);
893 if (res != OK) {
894 ALOGE("%s: Camera %d: Unable to submit still image capture request: "
895 "%s (%d)",
896 __FUNCTION__, mCameraId, strerror(-res), res);
897 return res;
898 }
899
900 switch (mState) {
901 case PREVIEW:
902 mState = STILL_CAPTURE;
903 break;
904 case RECORD:
905 mState = VIDEO_SNAPSHOT;
906 break;
907 default:
908 ALOGE("%s: Camera %d: Unknown state for still capture!",
909 __FUNCTION__, mCameraId);
910 return INVALID_OPERATION;
911 }
912
913 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700914}
915
916status_t Camera2Client::setParameters(const String8& params) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700917 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700918 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700919 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700920 LockedParameters::Key k(mParameters);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700921 status_t res;
922
923 CameraParameters newParams(params);
924
925 // TODO: Currently ignoring any changes to supposedly read-only
926 // parameters such as supported preview sizes, etc. Should probably
927 // produce an error if they're changed.
928
929 /** Extract and verify new parameters */
930
931 size_t i;
932
933 // PREVIEW_SIZE
934 int previewWidth, previewHeight;
935 newParams.getPreviewSize(&previewWidth, &previewHeight);
936
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700937 if (previewWidth != k.mParameters.previewWidth ||
938 previewHeight != k.mParameters.previewHeight) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700939 if (mState >= PREVIEW) {
940 ALOGE("%s: Preview size cannot be updated when preview "
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700941 "is active! (Currently %d x %d, requested %d x %d",
942 __FUNCTION__,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700943 k.mParameters.previewWidth, k.mParameters.previewHeight,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700944 previewWidth, previewHeight);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700945 return BAD_VALUE;
946 }
947 camera_metadata_entry_t availablePreviewSizes =
948 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
949 for (i = 0; i < availablePreviewSizes.count; i += 2 ) {
950 if (availablePreviewSizes.data.i32[i] == previewWidth &&
951 availablePreviewSizes.data.i32[i+1] == previewHeight) break;
952 }
953 if (i == availablePreviewSizes.count) {
954 ALOGE("%s: Requested preview size %d x %d is not supported",
955 __FUNCTION__, previewWidth, previewHeight);
956 return BAD_VALUE;
957 }
958 }
959
960 // PREVIEW_FPS_RANGE
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700961 int previewFpsRange[2];
962 int previewFps = 0;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700963 bool fpsRangeChanged = false;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700964 newParams.getPreviewFpsRange(&previewFpsRange[0], &previewFpsRange[1]);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700965 if (previewFpsRange[0] != k.mParameters.previewFpsRange[0] ||
966 previewFpsRange[1] != k.mParameters.previewFpsRange[1]) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700967 fpsRangeChanged = true;
968 camera_metadata_entry_t availablePreviewFpsRanges =
969 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
970 for (i = 0; i < availablePreviewFpsRanges.count; i += 2) {
971 if ((availablePreviewFpsRanges.data.i32[i] ==
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700972 previewFpsRange[0]) &&
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700973 (availablePreviewFpsRanges.data.i32[i+1] ==
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700974 previewFpsRange[1]) ) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700975 break;
976 }
977 }
978 if (i == availablePreviewFpsRanges.count) {
979 ALOGE("%s: Requested preview FPS range %d - %d is not supported",
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700980 __FUNCTION__, previewFpsRange[0], previewFpsRange[1]);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700981 return BAD_VALUE;
982 }
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700983 previewFps = previewFpsRange[0];
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700984 }
985
986 // PREVIEW_FORMAT
987 int previewFormat = formatStringToEnum(newParams.getPreviewFormat());
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700988 if (previewFormat != k.mParameters.previewFormat) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700989 if (mState >= PREVIEW) {
990 ALOGE("%s: Preview format cannot be updated when preview "
991 "is active!", __FUNCTION__);
992 return BAD_VALUE;
993 }
994 camera_metadata_entry_t availableFormats =
995 staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
996 for (i = 0; i < availableFormats.count; i++) {
997 if (availableFormats.data.i32[i] == previewFormat) break;
998 }
999 if (i == availableFormats.count) {
1000 ALOGE("%s: Requested preview format %s (0x%x) is not supported",
1001 __FUNCTION__, newParams.getPreviewFormat(), previewFormat);
1002 return BAD_VALUE;
1003 }
1004 }
1005
1006 // PREVIEW_FRAME_RATE
1007 // Deprecated, only use if the preview fps range is unchanged this time.
1008 // The single-value FPS is the same as the minimum of the range.
1009 if (!fpsRangeChanged) {
1010 previewFps = newParams.getPreviewFrameRate();
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001011 if (previewFps != k.mParameters.previewFps) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001012 camera_metadata_entry_t availableFrameRates =
1013 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
1014 for (i = 0; i < availableFrameRates.count; i+=2) {
1015 if (availableFrameRates.data.i32[i] == previewFps) break;
1016 }
1017 if (i == availableFrameRates.count) {
1018 ALOGE("%s: Requested preview frame rate %d is not supported",
1019 __FUNCTION__, previewFps);
1020 return BAD_VALUE;
1021 }
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001022 previewFpsRange[0] = availableFrameRates.data.i32[i];
1023 previewFpsRange[1] = availableFrameRates.data.i32[i+1];
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001024 }
1025 }
1026
1027 // PICTURE_SIZE
1028 int pictureWidth, pictureHeight;
1029 newParams.getPictureSize(&pictureWidth, &pictureHeight);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001030 if (pictureWidth == k.mParameters.pictureWidth ||
1031 pictureHeight == k.mParameters.pictureHeight) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001032 camera_metadata_entry_t availablePictureSizes =
1033 staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES);
1034 for (i = 0; i < availablePictureSizes.count; i+=2) {
1035 if (availablePictureSizes.data.i32[i] == pictureWidth &&
1036 availablePictureSizes.data.i32[i+1] == pictureHeight) break;
1037 }
1038 if (i == availablePictureSizes.count) {
1039 ALOGE("%s: Requested picture size %d x %d is not supported",
1040 __FUNCTION__, pictureWidth, pictureHeight);
1041 return BAD_VALUE;
1042 }
1043 }
1044
1045 // JPEG_THUMBNAIL_WIDTH/HEIGHT
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001046 int jpegThumbSize[2];
1047 jpegThumbSize[0] =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001048 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001049 jpegThumbSize[1] =
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001050 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001051 if (jpegThumbSize[0] != k.mParameters.jpegThumbSize[0] ||
1052 jpegThumbSize[1] != k.mParameters.jpegThumbSize[1]) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001053 camera_metadata_entry_t availableJpegThumbSizes =
1054 staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES);
1055 for (i = 0; i < availableJpegThumbSizes.count; i+=2) {
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001056 if (availableJpegThumbSizes.data.i32[i] == jpegThumbSize[0] &&
1057 availableJpegThumbSizes.data.i32[i+1] == jpegThumbSize[1]) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001058 break;
1059 }
1060 }
1061 if (i == availableJpegThumbSizes.count) {
1062 ALOGE("%s: Requested JPEG thumbnail size %d x %d is not supported",
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001063 __FUNCTION__, jpegThumbSize[0], jpegThumbSize[1]);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001064 return BAD_VALUE;
1065 }
1066 }
1067
1068 // JPEG_THUMBNAIL_QUALITY
1069 int jpegThumbQuality =
1070 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
1071 if (jpegThumbQuality < 0 || jpegThumbQuality > 100) {
1072 ALOGE("%s: Requested JPEG thumbnail quality %d is not supported",
1073 __FUNCTION__, jpegThumbQuality);
1074 return BAD_VALUE;
1075 }
1076
1077 // JPEG_QUALITY
1078 int jpegQuality =
1079 newParams.getInt(CameraParameters::KEY_JPEG_QUALITY);
1080 if (jpegQuality < 0 || jpegQuality > 100) {
1081 ALOGE("%s: Requested JPEG quality %d is not supported",
1082 __FUNCTION__, jpegQuality);
1083 return BAD_VALUE;
1084 }
1085
1086 // ROTATION
1087 int jpegRotation =
1088 newParams.getInt(CameraParameters::KEY_ROTATION);
1089 if (jpegRotation != 0 &&
1090 jpegRotation != 90 &&
1091 jpegRotation != 180 &&
1092 jpegRotation != 270) {
1093 ALOGE("%s: Requested picture rotation angle %d is not supported",
1094 __FUNCTION__, jpegRotation);
1095 return BAD_VALUE;
1096 }
1097
1098 // GPS
1099 bool gpsEnabled = false;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001100 double gpsCoordinates[3] = {0,0,0};
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001101 int64_t gpsTimestamp = 0;
1102 String8 gpsProcessingMethod;
1103 const char *gpsLatStr =
1104 newParams.get(CameraParameters::KEY_GPS_LATITUDE);
1105 if (gpsLatStr != NULL) {
1106 const char *gpsLongStr =
1107 newParams.get(CameraParameters::KEY_GPS_LONGITUDE);
1108 const char *gpsAltitudeStr =
1109 newParams.get(CameraParameters::KEY_GPS_ALTITUDE);
1110 const char *gpsTimeStr =
1111 newParams.get(CameraParameters::KEY_GPS_TIMESTAMP);
1112 const char *gpsProcMethodStr =
1113 newParams.get(CameraParameters::KEY_GPS_PROCESSING_METHOD);
1114 if (gpsLongStr == NULL ||
1115 gpsAltitudeStr == NULL ||
1116 gpsTimeStr == NULL ||
1117 gpsProcMethodStr == NULL) {
1118 ALOGE("%s: Incomplete set of GPS parameters provided",
1119 __FUNCTION__);
1120 return BAD_VALUE;
1121 }
1122 char *endPtr;
1123 errno = 0;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001124 gpsCoordinates[0] = strtod(gpsLatStr, &endPtr);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001125 if (errno || endPtr == gpsLatStr) {
1126 ALOGE("%s: Malformed GPS latitude: %s", __FUNCTION__, gpsLatStr);
1127 return BAD_VALUE;
1128 }
1129 errno = 0;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001130 gpsCoordinates[1] = strtod(gpsLongStr, &endPtr);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001131 if (errno || endPtr == gpsLongStr) {
1132 ALOGE("%s: Malformed GPS longitude: %s", __FUNCTION__, gpsLongStr);
1133 return BAD_VALUE;
1134 }
1135 errno = 0;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001136 gpsCoordinates[2] = strtod(gpsAltitudeStr, &endPtr);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001137 if (errno || endPtr == gpsAltitudeStr) {
1138 ALOGE("%s: Malformed GPS altitude: %s", __FUNCTION__,
1139 gpsAltitudeStr);
1140 return BAD_VALUE;
1141 }
1142 errno = 0;
1143 gpsTimestamp = strtoll(gpsTimeStr, &endPtr, 10);
1144 if (errno || endPtr == gpsTimeStr) {
1145 ALOGE("%s: Malformed GPS timestamp: %s", __FUNCTION__, gpsTimeStr);
1146 return BAD_VALUE;
1147 }
1148 gpsProcessingMethod = gpsProcMethodStr;
1149
1150 gpsEnabled = true;
1151 }
1152
1153 // WHITE_BALANCE
1154 int wbMode = wbModeStringToEnum(
1155 newParams.get(CameraParameters::KEY_WHITE_BALANCE) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001156 if (wbMode != k.mParameters.wbMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001157 camera_metadata_entry_t availableWbModes =
1158 staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
1159 for (i = 0; i < availableWbModes.count; i++) {
1160 if (wbMode == availableWbModes.data.u8[i]) break;
1161 }
1162 if (i == availableWbModes.count) {
1163 ALOGE("%s: Requested white balance mode %s is not supported",
1164 __FUNCTION__,
1165 newParams.get(CameraParameters::KEY_WHITE_BALANCE));
1166 return BAD_VALUE;
1167 }
1168 }
1169
1170 // EFFECT
1171 int effectMode = effectModeStringToEnum(
1172 newParams.get(CameraParameters::KEY_EFFECT) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001173 if (effectMode != k.mParameters.effectMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001174 camera_metadata_entry_t availableEffectModes =
1175 staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
1176 for (i = 0; i < availableEffectModes.count; i++) {
1177 if (effectMode == availableEffectModes.data.u8[i]) break;
1178 }
1179 if (i == availableEffectModes.count) {
1180 ALOGE("%s: Requested effect mode \"%s\" is not supported",
1181 __FUNCTION__,
1182 newParams.get(CameraParameters::KEY_EFFECT) );
1183 return BAD_VALUE;
1184 }
1185 }
1186
1187 // ANTIBANDING
1188 int antibandingMode = abModeStringToEnum(
1189 newParams.get(CameraParameters::KEY_ANTIBANDING) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001190 if (antibandingMode != k.mParameters.antibandingMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001191 camera_metadata_entry_t availableAbModes =
1192 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
1193 for (i = 0; i < availableAbModes.count; i++) {
1194 if (antibandingMode == availableAbModes.data.u8[i]) break;
1195 }
1196 if (i == availableAbModes.count) {
1197 ALOGE("%s: Requested antibanding mode \"%s\" is not supported",
1198 __FUNCTION__,
1199 newParams.get(CameraParameters::KEY_ANTIBANDING));
1200 return BAD_VALUE;
1201 }
1202 }
1203
1204 // SCENE_MODE
1205 int sceneMode = sceneModeStringToEnum(
1206 newParams.get(CameraParameters::KEY_SCENE_MODE) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001207 if (sceneMode != k.mParameters.sceneMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001208 camera_metadata_entry_t availableSceneModes =
1209 staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
1210 for (i = 0; i < availableSceneModes.count; i++) {
1211 if (sceneMode == availableSceneModes.data.u8[i]) break;
1212 }
1213 if (i == availableSceneModes.count) {
1214 ALOGE("%s: Requested scene mode \"%s\" is not supported",
1215 __FUNCTION__,
1216 newParams.get(CameraParameters::KEY_SCENE_MODE));
1217 return BAD_VALUE;
1218 }
1219 }
1220
1221 // FLASH_MODE
1222 Parameters::flashMode_t flashMode = flashModeStringToEnum(
1223 newParams.get(CameraParameters::KEY_FLASH_MODE) );
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001224 if (flashMode != k.mParameters.flashMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001225 camera_metadata_entry_t flashAvailable =
1226 staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
1227 if (!flashAvailable.data.u8[0] &&
1228 flashMode != Parameters::FLASH_MODE_OFF) {
1229 ALOGE("%s: Requested flash mode \"%s\" is not supported: "
1230 "No flash on device", __FUNCTION__,
1231 newParams.get(CameraParameters::KEY_FLASH_MODE));
1232 return BAD_VALUE;
1233 } else if (flashMode == Parameters::FLASH_MODE_RED_EYE) {
1234 camera_metadata_entry_t availableAeModes =
1235 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
1236 for (i = 0; i < availableAeModes.count; i++) {
1237 if (flashMode == availableAeModes.data.u8[i]) break;
1238 }
1239 if (i == availableAeModes.count) {
1240 ALOGE("%s: Requested flash mode \"%s\" is not supported",
1241 __FUNCTION__,
1242 newParams.get(CameraParameters::KEY_FLASH_MODE));
1243 return BAD_VALUE;
1244 }
1245 } else if (flashMode == -1) {
1246 ALOGE("%s: Requested flash mode \"%s\" is unknown",
1247 __FUNCTION__,
1248 newParams.get(CameraParameters::KEY_FLASH_MODE));
1249 return BAD_VALUE;
1250 }
1251 }
1252
1253 // FOCUS_MODE
1254 Parameters::focusMode_t focusMode = focusModeStringToEnum(
1255 newParams.get(CameraParameters::KEY_FOCUS_MODE));
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001256 if (focusMode != k.mParameters.focusMode) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001257 if (focusMode != Parameters::FOCUS_MODE_FIXED) {
1258 camera_metadata_entry_t minFocusDistance =
1259 staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE);
1260 if (minFocusDistance.data.f[0] == 0) {
1261 ALOGE("%s: Requested focus mode \"%s\" is not available: "
1262 "fixed focus lens",
1263 __FUNCTION__,
1264 newParams.get(CameraParameters::KEY_FOCUS_MODE));
1265 return BAD_VALUE;
1266 } else if (focusMode != Parameters::FOCUS_MODE_INFINITY) {
1267 camera_metadata_entry_t availableFocusModes =
1268 staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
1269 for (i = 0; i < availableFocusModes.count; i++) {
1270 if (focusMode == availableFocusModes.data.u8[i]) break;
1271 }
1272 if (i == availableFocusModes.count) {
1273 ALOGE("%s: Requested focus mode \"%s\" is not supported",
1274 __FUNCTION__,
1275 newParams.get(CameraParameters::KEY_FOCUS_MODE));
1276 return BAD_VALUE;
1277 }
1278 }
1279 }
1280 }
1281
1282 // FOCUS_AREAS
1283 Vector<Parameters::Area> focusingAreas;
1284 res = parseAreas(newParams.get(CameraParameters::KEY_FOCUS_AREAS),
1285 &focusingAreas);
1286 size_t max3aRegions =
1287 (size_t)staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1).data.i32[0];
1288 if (res == OK) res = validateAreas(focusingAreas, max3aRegions);
1289 if (res != OK) {
1290 ALOGE("%s: Requested focus areas are malformed: %s",
1291 __FUNCTION__, newParams.get(CameraParameters::KEY_FOCUS_AREAS));
1292 return BAD_VALUE;
1293 }
1294
1295 // EXPOSURE_COMPENSATION
1296 int exposureCompensation =
1297 newParams.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION);
1298 camera_metadata_entry_t exposureCompensationRange =
1299 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE);
1300 if (exposureCompensation < exposureCompensationRange.data.i32[0] ||
1301 exposureCompensation > exposureCompensationRange.data.i32[1]) {
1302 ALOGE("%s: Requested exposure compensation index is out of bounds: %d",
1303 __FUNCTION__, exposureCompensation);
1304 return BAD_VALUE;
1305 }
1306
1307 // AUTO_EXPOSURE_LOCK (always supported)
1308 bool autoExposureLock = boolFromString(
1309 newParams.get(CameraParameters::KEY_AUTO_EXPOSURE_LOCK));
1310
1311 // AUTO_WHITEBALANCE_LOCK (always supported)
1312 bool autoWhiteBalanceLock = boolFromString(
1313 newParams.get(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK));
1314
1315 // METERING_AREAS
1316 Vector<Parameters::Area> meteringAreas;
1317 res = parseAreas(newParams.get(CameraParameters::KEY_METERING_AREAS),
1318 &meteringAreas);
1319 if (res == OK) res = validateAreas(focusingAreas, max3aRegions);
1320 if (res != OK) {
1321 ALOGE("%s: Requested metering areas are malformed: %s",
1322 __FUNCTION__,
1323 newParams.get(CameraParameters::KEY_METERING_AREAS));
1324 return BAD_VALUE;
1325 }
1326
1327 // ZOOM
1328 int zoom = newParams.getInt(CameraParameters::KEY_ZOOM);
1329 if (zoom < 0 || zoom > (int)NUM_ZOOM_STEPS) {
1330 ALOGE("%s: Requested zoom level %d is not supported",
1331 __FUNCTION__, zoom);
1332 return BAD_VALUE;
1333 }
1334
1335 // VIDEO_SIZE
1336 int videoWidth, videoHeight;
1337 newParams.getVideoSize(&videoWidth, &videoHeight);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001338 if (videoWidth != k.mParameters.videoWidth ||
1339 videoHeight != k.mParameters.videoHeight) {
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001340 if (mState == RECORD) {
1341 ALOGE("%s: Video size cannot be updated when recording is active!",
1342 __FUNCTION__);
1343 return BAD_VALUE;
1344 }
1345 camera_metadata_entry_t availableVideoSizes =
1346 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
1347 for (i = 0; i < availableVideoSizes.count; i += 2 ) {
1348 if (availableVideoSizes.data.i32[i] == videoWidth &&
1349 availableVideoSizes.data.i32[i+1] == videoHeight) break;
1350 }
1351 if (i == availableVideoSizes.count) {
1352 ALOGE("%s: Requested video size %d x %d is not supported",
1353 __FUNCTION__, videoWidth, videoHeight);
1354 return BAD_VALUE;
1355 }
1356 }
1357
1358 // RECORDING_HINT (always supported)
1359 bool recordingHint = boolFromString(
1360 newParams.get(CameraParameters::KEY_RECORDING_HINT) );
1361
1362 // VIDEO_STABILIZATION
1363 bool videoStabilization = boolFromString(
1364 newParams.get(CameraParameters::KEY_VIDEO_STABILIZATION) );
1365 camera_metadata_entry_t availableVideoStabilizationModes =
1366 staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
1367 if (videoStabilization && availableVideoStabilizationModes.count == 1) {
1368 ALOGE("%s: Video stabilization not supported", __FUNCTION__);
1369 }
1370
1371 /** Update internal parameters */
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001372
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001373 k.mParameters.previewWidth = previewWidth;
1374 k.mParameters.previewHeight = previewHeight;
1375 k.mParameters.previewFpsRange[0] = previewFpsRange[0];
1376 k.mParameters.previewFpsRange[1] = previewFpsRange[1];
1377 k.mParameters.previewFps = previewFps;
1378 k.mParameters.previewFormat = previewFormat;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001379
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001380 k.mParameters.pictureWidth = pictureWidth;
1381 k.mParameters.pictureHeight = pictureHeight;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001382
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001383 k.mParameters.jpegThumbSize[0] = jpegThumbSize[0];
1384 k.mParameters.jpegThumbSize[1] = jpegThumbSize[1];
1385 k.mParameters.jpegQuality = jpegQuality;
1386 k.mParameters.jpegThumbQuality = jpegThumbQuality;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001387
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001388 k.mParameters.gpsEnabled = gpsEnabled;
1389 k.mParameters.gpsCoordinates[0] = gpsCoordinates[0];
1390 k.mParameters.gpsCoordinates[1] = gpsCoordinates[1];
1391 k.mParameters.gpsCoordinates[2] = gpsCoordinates[2];
1392 k.mParameters.gpsTimestamp = gpsTimestamp;
1393 k.mParameters.gpsProcessingMethod = gpsProcessingMethod;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001394
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001395 k.mParameters.wbMode = wbMode;
1396 k.mParameters.effectMode = effectMode;
1397 k.mParameters.antibandingMode = antibandingMode;
1398 k.mParameters.sceneMode = sceneMode;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001399
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001400 k.mParameters.flashMode = flashMode;
1401 k.mParameters.focusMode = focusMode;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001402
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001403 k.mParameters.focusingAreas = focusingAreas;
1404 k.mParameters.exposureCompensation = exposureCompensation;
1405 k.mParameters.autoExposureLock = autoExposureLock;
1406 k.mParameters.autoWhiteBalanceLock = autoWhiteBalanceLock;
1407 k.mParameters.meteringAreas = meteringAreas;
1408 k.mParameters.zoom = zoom;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001409
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001410 k.mParameters.videoWidth = videoWidth;
1411 k.mParameters.videoHeight = videoHeight;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001412
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001413 k.mParameters.recordingHint = recordingHint;
1414 k.mParameters.videoStabilization = videoStabilization;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001415
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001416 res = updatePreviewRequest(k.mParameters);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001417 if (res != OK) {
1418 ALOGE("%s: Camera %d: Unable to update preview request: %s (%d)",
1419 __FUNCTION__, mCameraId, strerror(-res), res);
1420 return res;
1421 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001422 res = updateCaptureRequest(k.mParameters);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001423 if (res != OK) {
1424 ALOGE("%s: Camera %d: Unable to update capture request: %s (%d)",
1425 __FUNCTION__, mCameraId, strerror(-res), res);
1426 return res;
1427 }
1428
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001429 res = updateRecordingRequest(k.mParameters);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001430 if (res != OK) {
1431 ALOGE("%s: Camera %d: Unable to update recording request: %s (%d)",
1432 __FUNCTION__, mCameraId, strerror(-res), res);
1433 return res;
1434 }
1435
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001436 if (mState == PREVIEW) {
1437 res = mDevice->setStreamingRequest(mPreviewRequest);
1438 if (res != OK) {
1439 ALOGE("%s: Camera %d: Error streaming new preview request: %s (%d)",
1440 __FUNCTION__, mCameraId, strerror(-res), res);
1441 return res;
1442 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001443 } else if (mState == RECORD || mState == VIDEO_SNAPSHOT) {
1444 res = mDevice->setStreamingRequest(mRecordingRequest);
1445 if (res != OK) {
1446 ALOGE("%s: Camera %d: Error streaming new record request: %s (%d)",
1447 __FUNCTION__, mCameraId, strerror(-res), res);
1448 return res;
1449 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001450 }
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001451
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001452 k.mParameters.paramsFlattened = params;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001453
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001454 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001455}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001456
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001457String8 Camera2Client::getParameters() const {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001458 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001459 Mutex::Autolock icl(mICameraLock);
1460
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001461 LockedParameters::ReadKey k(mParameters);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001462
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001463 // TODO: Deal with focus distances
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001464 return k.mParameters.paramsFlattened;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001465}
1466
1467status_t Camera2Client::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001468 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001469 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001470
1471 ALOGV("%s: Camera %d: Command %d (%d, %d)", __FUNCTION__, mCameraId,
1472 cmd, arg1, arg2);
1473
1474 if (cmd == CAMERA_CMD_SET_DISPLAY_ORIENTATION) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001475 LockedParameters::Key k(mParameters);
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001476 int transform = degToTransform(arg1,
1477 mCameraFacing == CAMERA_FACING_FRONT);
1478 if (transform == -1) {
1479 ALOGE("%s: Camera %d: Error setting %d as display orientation value",
1480 __FUNCTION__, mCameraId, arg1);
1481 return BAD_VALUE;
1482 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001483 if (transform != k.mParameters.previewTransform &&
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001484 mPreviewStreamId != NO_STREAM) {
1485 mDevice->setStreamTransform(mPreviewStreamId, transform);
1486 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001487 k.mParameters.previewTransform = transform;
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001488 return OK;
1489 }
1490
1491 ALOGE("%s: Camera %d: Unimplemented command %d (%d, %d)", __FUNCTION__,
1492 mCameraId, cmd, arg1, arg2);
1493
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001494 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001495}
1496
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001497/** Device-related methods */
1498
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001499void Camera2Client::onCaptureAvailable() {
1500 ATRACE_CALL();
1501 status_t res;
1502 sp<ICameraClient> currentClient;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001503 ALOGV("%s: Camera %d: Still capture available", __FUNCTION__, mCameraId);
1504
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001505 CpuConsumer::LockedBuffer imgBuffer;
1506 {
1507 Mutex::Autolock icl(mICameraLock);
1508
1509 // TODO: Signal errors here upstream
1510 if (mState != STILL_CAPTURE && mState != VIDEO_SNAPSHOT) {
1511 ALOGE("%s: Camera %d: Still image produced unexpectedly!",
1512 __FUNCTION__, mCameraId);
1513 return;
1514 }
1515
1516 res = mCaptureConsumer->lockNextBuffer(&imgBuffer);
1517 if (res != OK) {
1518 ALOGE("%s: Camera %d: Error receiving still image buffer: %s (%d)",
1519 __FUNCTION__, mCameraId, strerror(-res), res);
1520 return;
1521 }
1522
1523 if (imgBuffer.format != HAL_PIXEL_FORMAT_BLOB) {
1524 ALOGE("%s: Camera %d: Unexpected format for still image: "
1525 "%x, expected %x", __FUNCTION__, mCameraId,
1526 imgBuffer.format,
1527 HAL_PIXEL_FORMAT_BLOB);
1528 mCaptureConsumer->unlockBuffer(imgBuffer);
1529 return;
1530 }
1531
1532 // TODO: Optimize this to avoid memcopy
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001533 void* captureMemory = mCaptureHeap->mHeap->getBase();
1534 size_t size = mCaptureHeap->mHeap->getSize();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001535 memcpy(captureMemory, imgBuffer.data, size);
1536
1537 mCaptureConsumer->unlockBuffer(imgBuffer);
1538
1539 currentClient = mCameraClient;
1540 switch (mState) {
1541 case STILL_CAPTURE:
1542 mState = STOPPED;
1543 break;
1544 case VIDEO_SNAPSHOT:
1545 mState = RECORD;
1546 break;
1547 default:
1548 ALOGE("%s: Camera %d: Unexpected state %d", __FUNCTION__,
1549 mCameraId, mState);
1550 break;
1551 }
1552 }
1553 // Call outside mICameraLock to allow re-entrancy from notification
1554 if (currentClient != 0) {
1555 currentClient->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001556 mCaptureHeap->mBuffers[0], NULL);
1557 }
1558}
1559
1560void Camera2Client::onRecordingFrameAvailable() {
1561 ATRACE_CALL();
1562 status_t res;
1563 sp<ICameraClient> currentClient;
1564 size_t heapIdx = 0;
1565 nsecs_t timestamp;
1566 {
1567 Mutex::Autolock icl(mICameraLock);
1568 // TODO: Signal errors here upstream
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001569 bool discardData = false;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001570 if (mState != RECORD && mState != VIDEO_SNAPSHOT) {
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001571 ALOGV("%s: Camera %d: Discarding recording image buffers received after "
1572 "recording done",
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001573 __FUNCTION__, mCameraId);
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001574 discardData = true;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001575 }
1576
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001577 buffer_handle_t imgBuffer;
1578 res = mRecordingConsumer->getNextBuffer(&imgBuffer, &timestamp);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001579 if (res != OK) {
1580 ALOGE("%s: Camera %d: Error receiving recording buffer: %s (%d)",
1581 __FUNCTION__, mCameraId, strerror(-res), res);
1582 return;
1583 }
1584
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001585 if (discardData) {
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001586 mRecordingConsumer->freeBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001587 return;
1588 }
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001589
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001590 if (mRecordingHeap == 0) {
1591 const size_t bufferSize = 4 + sizeof(buffer_handle_t);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001592 ALOGV("%s: Camera %d: Creating recording heap with %d buffers of "
1593 "size %d bytes", __FUNCTION__, mCameraId,
1594 kRecordingHeapCount, bufferSize);
1595 if (mRecordingHeap != 0) {
1596 ALOGV("%s: Camera %d: Previous heap has size %d "
1597 "(new will be %d) bytes", __FUNCTION__, mCameraId,
1598 mRecordingHeap->mHeap->getSize(),
1599 bufferSize * kRecordingHeapCount);
1600 }
1601 // Need to allocate memory for heap
1602 mRecordingHeap.clear();
1603
1604 mRecordingHeap = new Camera2Heap(bufferSize, kRecordingHeapCount,
1605 "Camera2Client::RecordingHeap");
1606 if (mRecordingHeap->mHeap->getSize() == 0) {
1607 ALOGE("%s: Camera %d: Unable to allocate memory for recording",
1608 __FUNCTION__, mCameraId);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001609 mRecordingConsumer->freeBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001610 return;
1611 }
1612 mRecordingHeapHead = 0;
1613 mRecordingHeapFree = kRecordingHeapCount;
1614 }
1615
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001616 if ( mRecordingHeapFree == 0) {
1617 ALOGE("%s: Camera %d: No free recording buffers, dropping frame",
1618 __FUNCTION__, mCameraId);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001619 mRecordingConsumer->freeBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001620 return;
1621 }
1622 heapIdx = mRecordingHeapHead;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001623 mRecordingHeapHead = (mRecordingHeapHead + 1) % kRecordingHeapCount;
1624 mRecordingHeapFree--;
1625
1626 ALOGV("%s: Camera %d: Timestamp %lld",
1627 __FUNCTION__, mCameraId, timestamp);
1628
1629 ssize_t offset;
1630 size_t size;
1631 sp<IMemoryHeap> heap =
1632 mRecordingHeap->mBuffers[heapIdx]->getMemory(&offset,
1633 &size);
1634
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001635 uint8_t *data = (uint8_t*)heap->getBase() + offset;
1636 uint32_t type = kMetadataBufferTypeGrallocSource;
1637 memcpy(data, &type, 4);
1638 memcpy(data + 4, &imgBuffer, sizeof(buffer_handle_t));
1639 ALOGV("%s: Camera %d: Sending out buffer_handle_t %p",
Eino-Ville Talvala803cbf62012-07-25 15:23:36 -07001640 __FUNCTION__, mCameraId, imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001641 currentClient = mCameraClient;
1642 }
1643 // Call outside mICameraLock to allow re-entrancy from notification
1644 if (currentClient != 0) {
1645 currentClient->dataCallbackTimestamp(timestamp,
1646 CAMERA_MSG_VIDEO_FRAME,
1647 mRecordingHeap->mBuffers[heapIdx]);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001648 }
1649}
1650
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001651camera_metadata_entry_t Camera2Client::staticInfo(uint32_t tag,
1652 size_t minCount, size_t maxCount) {
1653 status_t res;
1654 camera_metadata_entry_t entry;
1655 res = find_camera_metadata_entry(mDevice->info(),
1656 tag,
1657 &entry);
1658 if (CC_UNLIKELY( res != OK )) {
1659 const char* tagSection = get_camera_metadata_section_name(tag);
1660 if (tagSection == NULL) tagSection = "<unknown>";
1661 const char* tagName = get_camera_metadata_tag_name(tag);
1662 if (tagName == NULL) tagName = "<unknown>";
1663
1664 ALOGE("Error finding static metadata entry '%s.%s' (%x): %s (%d)",
1665 tagSection, tagName, tag, strerror(-res), res);
1666 entry.count = 0;
1667 entry.data.u8 = NULL;
1668 } else if (CC_UNLIKELY(
1669 (minCount != 0 && entry.count < minCount) ||
1670 (maxCount != 0 && entry.count > maxCount) ) ) {
1671 const char* tagSection = get_camera_metadata_section_name(tag);
1672 if (tagSection == NULL) tagSection = "<unknown>";
1673 const char* tagName = get_camera_metadata_tag_name(tag);
1674 if (tagName == NULL) tagName = "<unknown>";
1675 ALOGE("Malformed static metadata entry '%s.%s' (%x):"
1676 "Expected between %d and %d values, but got %d values",
1677 tagSection, tagName, tag, minCount, maxCount, entry.count);
1678 entry.count = 0;
1679 entry.data.u8 = NULL;
1680 }
1681
1682 return entry;
1683}
1684
1685/** Utility methods */
1686
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001687
1688status_t Camera2Client::buildDefaultParameters() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001689 ATRACE_CALL();
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001690 LockedParameters::Key k(mParameters);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001691
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001692 status_t res;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001693 CameraParameters params;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001694
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001695 camera_metadata_entry_t availableProcessedSizes =
1696 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES, 2);
1697 if (!availableProcessedSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001698
1699 // TODO: Pick more intelligently
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001700 k.mParameters.previewWidth = availableProcessedSizes.data.i32[0];
1701 k.mParameters.previewHeight = availableProcessedSizes.data.i32[1];
1702 k.mParameters.videoWidth = k.mParameters.previewWidth;
1703 k.mParameters.videoHeight = k.mParameters.previewHeight;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001704
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001705 params.setPreviewSize(k.mParameters.previewWidth, k.mParameters.previewHeight);
1706 params.setVideoSize(k.mParameters.videoWidth, k.mParameters.videoHeight);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001707 params.set(CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO,
1708 String8::format("%dx%d",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001709 k.mParameters.previewWidth, k.mParameters.previewHeight));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001710 {
1711 String8 supportedPreviewSizes;
1712 for (size_t i=0; i < availableProcessedSizes.count; i += 2) {
1713 if (i != 0) supportedPreviewSizes += ",";
1714 supportedPreviewSizes += String8::format("%dx%d",
1715 availableProcessedSizes.data.i32[i],
1716 availableProcessedSizes.data.i32[i+1]);
1717 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001718 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001719 supportedPreviewSizes);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001720 params.set(CameraParameters::KEY_SUPPORTED_VIDEO_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001721 supportedPreviewSizes);
1722 }
1723
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001724 camera_metadata_entry_t availableFpsRanges =
1725 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
1726 if (!availableFpsRanges.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001727
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001728 k.mParameters.previewFpsRange[0] = availableFpsRanges.data.i32[0];
1729 k.mParameters.previewFpsRange[1] = availableFpsRanges.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001730
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001731 params.set(CameraParameters::KEY_PREVIEW_FPS_RANGE,
1732 String8::format("%d,%d",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001733 k.mParameters.previewFpsRange[0],
1734 k.mParameters.previewFpsRange[1]));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001735
1736 {
1737 String8 supportedPreviewFpsRange;
1738 for (size_t i=0; i < availableFpsRanges.count; i += 2) {
1739 if (i != 0) supportedPreviewFpsRange += ",";
1740 supportedPreviewFpsRange += String8::format("(%d,%d)",
1741 availableFpsRanges.data.i32[i],
1742 availableFpsRanges.data.i32[i+1]);
1743 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001744 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001745 supportedPreviewFpsRange);
1746 }
1747
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001748 k.mParameters.previewFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001749 params.set(CameraParameters::KEY_PREVIEW_FORMAT,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001750 formatEnumToString(k.mParameters.previewFormat)); // NV21
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001751
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001752 k.mParameters.previewTransform = degToTransform(0,
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001753 mCameraFacing == CAMERA_FACING_FRONT);
1754
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001755 camera_metadata_entry_t availableFormats =
1756 staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
1757
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001758 {
1759 String8 supportedPreviewFormats;
1760 bool addComma = false;
1761 for (size_t i=0; i < availableFormats.count; i++) {
1762 if (addComma) supportedPreviewFormats += ",";
1763 addComma = true;
1764 switch (availableFormats.data.i32[i]) {
1765 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001766 supportedPreviewFormats +=
1767 CameraParameters::PIXEL_FORMAT_YUV422SP;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001768 break;
1769 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001770 supportedPreviewFormats +=
1771 CameraParameters::PIXEL_FORMAT_YUV420SP;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001772 break;
1773 case HAL_PIXEL_FORMAT_YCbCr_422_I:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001774 supportedPreviewFormats +=
1775 CameraParameters::PIXEL_FORMAT_YUV422I;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001776 break;
1777 case HAL_PIXEL_FORMAT_YV12:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001778 supportedPreviewFormats +=
1779 CameraParameters::PIXEL_FORMAT_YUV420P;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001780 break;
1781 case HAL_PIXEL_FORMAT_RGB_565:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001782 supportedPreviewFormats +=
1783 CameraParameters::PIXEL_FORMAT_RGB565;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001784 break;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001785 case HAL_PIXEL_FORMAT_RGBA_8888:
1786 supportedPreviewFormats +=
1787 CameraParameters::PIXEL_FORMAT_RGBA8888;
1788 break;
1789 // Not advertizing JPEG, RAW_SENSOR, etc, for preview formats
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001790 case HAL_PIXEL_FORMAT_RAW_SENSOR:
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001791 case HAL_PIXEL_FORMAT_BLOB:
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001792 addComma = false;
1793 break;
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -07001794
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001795 default:
1796 ALOGW("%s: Camera %d: Unknown preview format: %x",
1797 __FUNCTION__, mCameraId, availableFormats.data.i32[i]);
1798 addComma = false;
1799 break;
1800 }
1801 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001802 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001803 supportedPreviewFormats);
1804 }
1805
1806 // PREVIEW_FRAME_RATE / SUPPORTED_PREVIEW_FRAME_RATES are deprecated, but
1807 // still have to do something sane for them
1808
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001809 params.set(CameraParameters::KEY_PREVIEW_FRAME_RATE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001810 k.mParameters.previewFpsRange[0]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001811
1812 {
1813 String8 supportedPreviewFrameRates;
1814 for (size_t i=0; i < availableFpsRanges.count; i += 2) {
1815 if (i != 0) supportedPreviewFrameRates += ",";
1816 supportedPreviewFrameRates += String8::format("%d",
1817 availableFpsRanges.data.i32[i]);
1818 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001819 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001820 supportedPreviewFrameRates);
1821 }
1822
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001823 camera_metadata_entry_t availableJpegSizes =
1824 staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES, 2);
1825 if (!availableJpegSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001826
1827 // TODO: Pick maximum
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001828 k.mParameters.pictureWidth = availableJpegSizes.data.i32[0];
1829 k.mParameters.pictureHeight = availableJpegSizes.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001830
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001831 params.setPictureSize(k.mParameters.pictureWidth,
1832 k.mParameters.pictureHeight);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001833
1834 {
1835 String8 supportedPictureSizes;
1836 for (size_t i=0; i < availableJpegSizes.count; i += 2) {
1837 if (i != 0) supportedPictureSizes += ",";
1838 supportedPictureSizes += String8::format("%dx%d",
1839 availableJpegSizes.data.i32[i],
1840 availableJpegSizes.data.i32[i+1]);
1841 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001842 params.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001843 supportedPictureSizes);
1844 }
1845
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001846 params.setPictureFormat(CameraParameters::PIXEL_FORMAT_JPEG);
1847 params.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS,
1848 CameraParameters::PIXEL_FORMAT_JPEG);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001849
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001850 camera_metadata_entry_t availableJpegThumbnailSizes =
1851 staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES, 2);
1852 if (!availableJpegThumbnailSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001853
1854 // TODO: Pick default thumbnail size sensibly
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001855 k.mParameters.jpegThumbSize[0] = availableJpegThumbnailSizes.data.i32[0];
1856 k.mParameters.jpegThumbSize[1] = availableJpegThumbnailSizes.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001857
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001858 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001859 k.mParameters.jpegThumbSize[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001860 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001861 k.mParameters.jpegThumbSize[1]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001862
1863 {
1864 String8 supportedJpegThumbSizes;
1865 for (size_t i=0; i < availableJpegThumbnailSizes.count; i += 2) {
1866 if (i != 0) supportedJpegThumbSizes += ",";
1867 supportedJpegThumbSizes += String8::format("%dx%d",
1868 availableJpegThumbnailSizes.data.i32[i],
1869 availableJpegThumbnailSizes.data.i32[i+1]);
1870 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001871 params.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001872 supportedJpegThumbSizes);
1873 }
1874
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001875 k.mParameters.jpegThumbQuality = 90;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001876 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001877 k.mParameters.jpegThumbQuality);
1878 k.mParameters.jpegQuality = 90;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001879 params.set(CameraParameters::KEY_JPEG_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001880 k.mParameters.jpegQuality);
1881 k.mParameters.jpegRotation = 0;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001882 params.set(CameraParameters::KEY_ROTATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001883 k.mParameters.jpegRotation);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001884
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001885 k.mParameters.gpsEnabled = false;
1886 k.mParameters.gpsProcessingMethod = "unknown";
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001887 // GPS fields in CameraParameters are not set by implementation
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001888
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001889 k.mParameters.wbMode = ANDROID_CONTROL_AWB_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001890 params.set(CameraParameters::KEY_WHITE_BALANCE,
1891 CameraParameters::WHITE_BALANCE_AUTO);
1892
1893 camera_metadata_entry_t availableWhiteBalanceModes =
1894 staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001895 {
1896 String8 supportedWhiteBalance;
1897 bool addComma = false;
1898 for (size_t i=0; i < availableWhiteBalanceModes.count; i++) {
1899 if (addComma) supportedWhiteBalance += ",";
1900 addComma = true;
1901 switch (availableWhiteBalanceModes.data.u8[i]) {
1902 case ANDROID_CONTROL_AWB_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001903 supportedWhiteBalance +=
1904 CameraParameters::WHITE_BALANCE_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001905 break;
1906 case ANDROID_CONTROL_AWB_INCANDESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001907 supportedWhiteBalance +=
1908 CameraParameters::WHITE_BALANCE_INCANDESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001909 break;
1910 case ANDROID_CONTROL_AWB_FLUORESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001911 supportedWhiteBalance +=
1912 CameraParameters::WHITE_BALANCE_FLUORESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001913 break;
1914 case ANDROID_CONTROL_AWB_WARM_FLUORESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001915 supportedWhiteBalance +=
1916 CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001917 break;
1918 case ANDROID_CONTROL_AWB_DAYLIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001919 supportedWhiteBalance +=
1920 CameraParameters::WHITE_BALANCE_DAYLIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001921 break;
1922 case ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001923 supportedWhiteBalance +=
1924 CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001925 break;
1926 case ANDROID_CONTROL_AWB_TWILIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001927 supportedWhiteBalance +=
1928 CameraParameters::WHITE_BALANCE_TWILIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001929 break;
1930 case ANDROID_CONTROL_AWB_SHADE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001931 supportedWhiteBalance +=
1932 CameraParameters::WHITE_BALANCE_SHADE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001933 break;
1934 // Skipping values not mappable to v1 API
1935 case ANDROID_CONTROL_AWB_OFF:
1936 addComma = false;
1937 break;
1938 default:
1939 ALOGW("%s: Camera %d: Unknown white balance value: %d",
1940 __FUNCTION__, mCameraId,
1941 availableWhiteBalanceModes.data.u8[i]);
1942 addComma = false;
1943 break;
1944 }
1945 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001946 params.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001947 supportedWhiteBalance);
1948 }
1949
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001950 k.mParameters.effectMode = ANDROID_CONTROL_EFFECT_OFF;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001951 params.set(CameraParameters::KEY_EFFECT,
1952 CameraParameters::EFFECT_NONE);
1953
1954 camera_metadata_entry_t availableEffects =
1955 staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
1956 if (!availableEffects.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001957 {
1958 String8 supportedEffects;
1959 bool addComma = false;
1960 for (size_t i=0; i < availableEffects.count; i++) {
1961 if (addComma) supportedEffects += ",";
1962 addComma = true;
1963 switch (availableEffects.data.u8[i]) {
1964 case ANDROID_CONTROL_EFFECT_OFF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001965 supportedEffects +=
1966 CameraParameters::EFFECT_NONE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001967 break;
1968 case ANDROID_CONTROL_EFFECT_MONO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001969 supportedEffects +=
1970 CameraParameters::EFFECT_MONO;
1971 break;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001972 case ANDROID_CONTROL_EFFECT_NEGATIVE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001973 supportedEffects +=
1974 CameraParameters::EFFECT_NEGATIVE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001975 break;
1976 case ANDROID_CONTROL_EFFECT_SOLARIZE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001977 supportedEffects +=
1978 CameraParameters::EFFECT_SOLARIZE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001979 break;
1980 case ANDROID_CONTROL_EFFECT_SEPIA:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001981 supportedEffects +=
1982 CameraParameters::EFFECT_SEPIA;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001983 break;
1984 case ANDROID_CONTROL_EFFECT_POSTERIZE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001985 supportedEffects +=
1986 CameraParameters::EFFECT_POSTERIZE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001987 break;
1988 case ANDROID_CONTROL_EFFECT_WHITEBOARD:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001989 supportedEffects +=
1990 CameraParameters::EFFECT_WHITEBOARD;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001991 break;
1992 case ANDROID_CONTROL_EFFECT_BLACKBOARD:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001993 supportedEffects +=
1994 CameraParameters::EFFECT_BLACKBOARD;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001995 break;
1996 case ANDROID_CONTROL_EFFECT_AQUA:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001997 supportedEffects +=
1998 CameraParameters::EFFECT_AQUA;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001999 break;
2000 default:
2001 ALOGW("%s: Camera %d: Unknown effect value: %d",
2002 __FUNCTION__, mCameraId, availableEffects.data.u8[i]);
2003 addComma = false;
2004 break;
2005 }
2006 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002007 params.set(CameraParameters::KEY_SUPPORTED_EFFECTS, supportedEffects);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002008 }
2009
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002010 k.mParameters.antibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002011 params.set(CameraParameters::KEY_ANTIBANDING,
2012 CameraParameters::ANTIBANDING_AUTO);
2013
2014 camera_metadata_entry_t availableAntibandingModes =
2015 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
2016 if (!availableAntibandingModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002017 {
2018 String8 supportedAntibanding;
2019 bool addComma = false;
2020 for (size_t i=0; i < availableAntibandingModes.count; i++) {
2021 if (addComma) supportedAntibanding += ",";
2022 addComma = true;
2023 switch (availableAntibandingModes.data.u8[i]) {
2024 case ANDROID_CONTROL_AE_ANTIBANDING_OFF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002025 supportedAntibanding +=
2026 CameraParameters::ANTIBANDING_OFF;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002027 break;
2028 case ANDROID_CONTROL_AE_ANTIBANDING_50HZ:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002029 supportedAntibanding +=
2030 CameraParameters::ANTIBANDING_50HZ;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002031 break;
2032 case ANDROID_CONTROL_AE_ANTIBANDING_60HZ:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002033 supportedAntibanding +=
2034 CameraParameters::ANTIBANDING_60HZ;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002035 break;
2036 case ANDROID_CONTROL_AE_ANTIBANDING_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002037 supportedAntibanding +=
2038 CameraParameters::ANTIBANDING_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002039 break;
2040 default:
2041 ALOGW("%s: Camera %d: Unknown antibanding value: %d",
2042 __FUNCTION__, mCameraId,
2043 availableAntibandingModes.data.u8[i]);
2044 addComma = false;
2045 break;
2046 }
2047 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002048 params.set(CameraParameters::KEY_SUPPORTED_ANTIBANDING,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002049 supportedAntibanding);
2050 }
2051
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002052 k.mParameters.sceneMode = ANDROID_CONTROL_OFF;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002053 params.set(CameraParameters::KEY_SCENE_MODE,
2054 CameraParameters::SCENE_MODE_AUTO);
2055
2056 camera_metadata_entry_t availableSceneModes =
2057 staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
2058 if (!availableSceneModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002059 {
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002060 String8 supportedSceneModes(CameraParameters::SCENE_MODE_AUTO);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002061 bool addComma = true;
2062 bool noSceneModes = false;
2063 for (size_t i=0; i < availableSceneModes.count; i++) {
2064 if (addComma) supportedSceneModes += ",";
2065 addComma = true;
2066 switch (availableSceneModes.data.u8[i]) {
2067 case ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED:
2068 noSceneModes = true;
2069 break;
2070 case ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY:
2071 // Not in old API
2072 addComma = false;
2073 break;
2074 case ANDROID_CONTROL_SCENE_MODE_ACTION:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002075 supportedSceneModes +=
2076 CameraParameters::SCENE_MODE_ACTION;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002077 break;
2078 case ANDROID_CONTROL_SCENE_MODE_PORTRAIT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002079 supportedSceneModes +=
2080 CameraParameters::SCENE_MODE_PORTRAIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002081 break;
2082 case ANDROID_CONTROL_SCENE_MODE_LANDSCAPE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002083 supportedSceneModes +=
2084 CameraParameters::SCENE_MODE_LANDSCAPE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002085 break;
2086 case ANDROID_CONTROL_SCENE_MODE_NIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002087 supportedSceneModes +=
2088 CameraParameters::SCENE_MODE_NIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002089 break;
2090 case ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002091 supportedSceneModes +=
2092 CameraParameters::SCENE_MODE_NIGHT_PORTRAIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002093 break;
2094 case ANDROID_CONTROL_SCENE_MODE_THEATRE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002095 supportedSceneModes +=
2096 CameraParameters::SCENE_MODE_THEATRE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002097 break;
2098 case ANDROID_CONTROL_SCENE_MODE_BEACH:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002099 supportedSceneModes +=
2100 CameraParameters::SCENE_MODE_BEACH;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002101 break;
2102 case ANDROID_CONTROL_SCENE_MODE_SNOW:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002103 supportedSceneModes +=
2104 CameraParameters::SCENE_MODE_SNOW;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002105 break;
2106 case ANDROID_CONTROL_SCENE_MODE_SUNSET:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002107 supportedSceneModes +=
2108 CameraParameters::SCENE_MODE_SUNSET;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002109 break;
2110 case ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002111 supportedSceneModes +=
2112 CameraParameters::SCENE_MODE_STEADYPHOTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002113 break;
2114 case ANDROID_CONTROL_SCENE_MODE_FIREWORKS:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002115 supportedSceneModes +=
2116 CameraParameters::SCENE_MODE_FIREWORKS;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002117 break;
2118 case ANDROID_CONTROL_SCENE_MODE_SPORTS:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002119 supportedSceneModes +=
2120 CameraParameters::SCENE_MODE_SPORTS;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002121 break;
2122 case ANDROID_CONTROL_SCENE_MODE_PARTY:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002123 supportedSceneModes +=
2124 CameraParameters::SCENE_MODE_PARTY;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002125 break;
2126 case ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002127 supportedSceneModes +=
2128 CameraParameters::SCENE_MODE_CANDLELIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002129 break;
2130 case ANDROID_CONTROL_SCENE_MODE_BARCODE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002131 supportedSceneModes +=
2132 CameraParameters::SCENE_MODE_BARCODE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002133 break;
2134 default:
2135 ALOGW("%s: Camera %d: Unknown scene mode value: %d",
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002136 __FUNCTION__, mCameraId,
2137 availableSceneModes.data.u8[i]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002138 addComma = false;
2139 break;
2140 }
2141 }
2142 if (!noSceneModes) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002143 params.set(CameraParameters::KEY_SUPPORTED_SCENE_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002144 supportedSceneModes);
2145 }
2146 }
2147
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002148 camera_metadata_entry_t flashAvailable =
2149 staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
2150 if (!flashAvailable.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002151
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002152 camera_metadata_entry_t availableAeModes =
2153 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
2154 if (!availableAeModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002155
2156 if (flashAvailable.data.u8[0]) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002157 k.mParameters.flashMode = Parameters::FLASH_MODE_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002158 params.set(CameraParameters::KEY_FLASH_MODE,
2159 CameraParameters::FLASH_MODE_AUTO);
2160
2161 String8 supportedFlashModes(CameraParameters::FLASH_MODE_OFF);
2162 supportedFlashModes = supportedFlashModes +
2163 "," + CameraParameters::FLASH_MODE_AUTO +
2164 "," + CameraParameters::FLASH_MODE_ON +
2165 "," + CameraParameters::FLASH_MODE_TORCH;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002166 for (size_t i=0; i < availableAeModes.count; i++) {
2167 if (availableAeModes.data.u8[i] ==
2168 ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002169 supportedFlashModes = supportedFlashModes + "," +
2170 CameraParameters::FLASH_MODE_RED_EYE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002171 break;
2172 }
2173 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002174 params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002175 supportedFlashModes);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002176 } else {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002177 k.mParameters.flashMode = Parameters::FLASH_MODE_OFF;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002178 params.set(CameraParameters::KEY_FLASH_MODE,
2179 CameraParameters::FLASH_MODE_OFF);
2180 params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
2181 CameraParameters::FLASH_MODE_OFF);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002182 }
2183
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002184 camera_metadata_entry_t minFocusDistance =
2185 staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE, 1, 1);
2186 if (!minFocusDistance.count) return NO_INIT;
2187
2188 camera_metadata_entry_t availableAfModes =
2189 staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
2190 if (!availableAfModes.count) return NO_INIT;
2191
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002192 if (minFocusDistance.data.f[0] == 0) {
2193 // Fixed-focus lens
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002194 k.mParameters.focusMode = Parameters::FOCUS_MODE_FIXED;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002195 params.set(CameraParameters::KEY_FOCUS_MODE,
2196 CameraParameters::FOCUS_MODE_FIXED);
2197 params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
2198 CameraParameters::FOCUS_MODE_FIXED);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002199 } else {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002200 k.mParameters.focusMode = Parameters::FOCUS_MODE_AUTO;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002201 params.set(CameraParameters::KEY_FOCUS_MODE,
2202 CameraParameters::FOCUS_MODE_AUTO);
2203 String8 supportedFocusModes(CameraParameters::FOCUS_MODE_FIXED);
2204 supportedFocusModes = supportedFocusModes + "," +
2205 CameraParameters::FOCUS_MODE_INFINITY;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002206 bool addComma = true;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002207
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002208 for (size_t i=0; i < availableAfModes.count; i++) {
2209 if (addComma) supportedFocusModes += ",";
2210 addComma = true;
2211 switch (availableAfModes.data.u8[i]) {
2212 case ANDROID_CONTROL_AF_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002213 supportedFocusModes +=
2214 CameraParameters::FOCUS_MODE_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002215 break;
2216 case ANDROID_CONTROL_AF_MACRO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002217 supportedFocusModes +=
2218 CameraParameters::FOCUS_MODE_MACRO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002219 break;
2220 case ANDROID_CONTROL_AF_CONTINUOUS_VIDEO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002221 supportedFocusModes +=
2222 CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002223 break;
2224 case ANDROID_CONTROL_AF_CONTINUOUS_PICTURE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002225 supportedFocusModes +=
2226 CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002227 break;
2228 case ANDROID_CONTROL_AF_EDOF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002229 supportedFocusModes +=
2230 CameraParameters::FOCUS_MODE_EDOF;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002231 break;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07002232 // Not supported in old API
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002233 case ANDROID_CONTROL_AF_OFF:
2234 addComma = false;
2235 break;
2236 default:
2237 ALOGW("%s: Camera %d: Unknown AF mode value: %d",
2238 __FUNCTION__, mCameraId, availableAfModes.data.u8[i]);
2239 addComma = false;
2240 break;
2241 }
2242 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002243 params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002244 supportedFocusModes);
2245 }
2246
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002247 camera_metadata_entry_t max3aRegions =
2248 staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1);
2249 if (!max3aRegions.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002250
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002251 params.set(CameraParameters::KEY_MAX_NUM_FOCUS_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002252 max3aRegions.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002253 params.set(CameraParameters::KEY_FOCUS_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002254 "(0,0,0,0,0)");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002255 k.mParameters.focusingAreas.clear();
2256 k.mParameters.focusingAreas.add(Parameters::Area(0,0,0,0,0));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002257
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002258 camera_metadata_entry_t availableFocalLengths =
2259 staticInfo(ANDROID_LENS_AVAILABLE_FOCAL_LENGTHS);
2260 if (!availableFocalLengths.count) return NO_INIT;
2261
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002262 float minFocalLength = availableFocalLengths.data.f[0];
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002263 params.setFloat(CameraParameters::KEY_FOCAL_LENGTH, minFocalLength);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002264
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002265 camera_metadata_entry_t sensorSize =
2266 staticInfo(ANDROID_SENSOR_PHYSICAL_SIZE, 2, 2);
2267 if (!sensorSize.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002268
2269 // The fields of view here assume infinity focus, maximum wide angle
2270 float horizFov = 180 / M_PI *
2271 2 * atanf(sensorSize.data.f[0] / (2 * minFocalLength));
2272 float vertFov = 180 / M_PI *
2273 2 * atanf(sensorSize.data.f[1] / (2 * minFocalLength));
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002274 params.setFloat(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, horizFov);
2275 params.setFloat(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, vertFov);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002276
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002277 k.mParameters.exposureCompensation = 0;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002278 params.set(CameraParameters::KEY_EXPOSURE_COMPENSATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002279 k.mParameters.exposureCompensation);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002280
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002281 camera_metadata_entry_t exposureCompensationRange =
2282 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE, 2, 2);
2283 if (!exposureCompensationRange.count) return NO_INIT;
2284
2285 params.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002286 exposureCompensationRange.data.i32[1]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002287 params.set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002288 exposureCompensationRange.data.i32[0]);
2289
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002290 camera_metadata_entry_t exposureCompensationStep =
2291 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_STEP, 1, 1);
2292 if (!exposureCompensationStep.count) return NO_INIT;
2293
2294 params.setFloat(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002295 exposureCompensationStep.data.r[0].numerator /
2296 exposureCompensationStep.data.r[0].denominator);
2297
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002298 k.mParameters.autoExposureLock = false;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002299 params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK,
2300 CameraParameters::FALSE);
2301 params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED,
2302 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002303
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002304 k.mParameters.autoWhiteBalanceLock = false;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002305 params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK,
2306 CameraParameters::FALSE);
2307 params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED,
2308 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002309
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002310 k.mParameters.meteringAreas.add(Parameters::Area(0, 0, 0, 0, 0));
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002311 params.set(CameraParameters::KEY_MAX_NUM_METERING_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002312 max3aRegions.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002313 params.set(CameraParameters::KEY_METERING_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002314 "(0,0,0,0,0)");
2315
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002316 k.mParameters.zoom = 0;
2317 params.set(CameraParameters::KEY_ZOOM, k.mParameters.zoom);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002318 params.set(CameraParameters::KEY_MAX_ZOOM, NUM_ZOOM_STEPS - 1);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002319
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002320 camera_metadata_entry_t maxDigitalZoom =
2321 staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM, 1, 1);
2322 if (!maxDigitalZoom.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002323
2324 {
2325 String8 zoomRatios;
2326 float zoom = 1.f;
2327 float zoomIncrement = (maxDigitalZoom.data.f[0] - zoom) /
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002328 (NUM_ZOOM_STEPS-1);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002329 bool addComma = false;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002330 for (size_t i=0; i < NUM_ZOOM_STEPS; i++) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002331 if (addComma) zoomRatios += ",";
2332 addComma = true;
2333 zoomRatios += String8::format("%d", static_cast<int>(zoom * 100));
2334 zoom += zoomIncrement;
2335 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002336 params.set(CameraParameters::KEY_ZOOM_RATIOS, zoomRatios);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002337 }
2338
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002339 params.set(CameraParameters::KEY_ZOOM_SUPPORTED,
2340 CameraParameters::TRUE);
2341 params.set(CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED,
2342 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002343
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002344 params.set(CameraParameters::KEY_FOCUS_DISTANCES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002345 "Infinity,Infinity,Infinity");
2346
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002347 camera_metadata_entry_t maxFacesDetected =
2348 staticInfo(ANDROID_STATS_MAX_FACE_COUNT, 1, 1);
2349 params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002350 maxFacesDetected.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002351 params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002352 0);
2353
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002354 params.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT,
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002355 CameraParameters::PIXEL_FORMAT_ANDROID_OPAQUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002356
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002357 params.set(CameraParameters::KEY_RECORDING_HINT,
2358 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002359
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002360 params.set(CameraParameters::KEY_VIDEO_SNAPSHOT_SUPPORTED,
2361 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002362
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002363 params.set(CameraParameters::KEY_VIDEO_STABILIZATION,
2364 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002365
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002366 camera_metadata_entry_t availableVideoStabilizationModes =
2367 staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
2368 if (!availableVideoStabilizationModes.count) return NO_INIT;
2369
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002370 if (availableVideoStabilizationModes.count > 1) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002371 params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
2372 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002373 } else {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002374 params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
2375 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002376 }
2377
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002378 // Always use metadata mode for recording
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002379 k.mParameters.storeMetadataInBuffers = true;
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002380
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002381 k.mParameters.paramsFlattened = params.flatten();
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002382
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07002383 return OK;
2384}
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07002385
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002386status_t Camera2Client::updatePreviewStream(const Parameters &params) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002387 ATRACE_CALL();
2388 status_t res;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002389
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002390 if (mPreviewStreamId != NO_STREAM) {
2391 // Check if stream parameters have to change
2392 uint32_t currentWidth, currentHeight;
2393 res = mDevice->getStreamInfo(mPreviewStreamId,
2394 &currentWidth, &currentHeight, 0);
2395 if (res != OK) {
2396 ALOGE("%s: Camera %d: Error querying preview stream info: "
2397 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2398 return res;
2399 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002400 if (currentWidth != (uint32_t)params.previewWidth ||
2401 currentHeight != (uint32_t)params.previewHeight) {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -07002402 ALOGV("%s: Camera %d: Preview size switch: %d x %d -> %d x %d",
2403 __FUNCTION__, mCameraId, currentWidth, currentHeight,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002404 params.previewWidth, params.previewHeight);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002405 res = mDevice->waitUntilDrained();
2406 if (res != OK) {
2407 ALOGE("%s: Camera %d: Error waiting for preview to drain: "
2408 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2409 return res;
2410 }
2411 res = mDevice->deleteStream(mPreviewStreamId);
2412 if (res != OK) {
2413 ALOGE("%s: Camera %d: Unable to delete old output stream "
2414 "for preview: %s (%d)", __FUNCTION__, mCameraId,
2415 strerror(-res), res);
2416 return res;
2417 }
2418 mPreviewStreamId = NO_STREAM;
2419 }
2420 }
2421
2422 if (mPreviewStreamId == NO_STREAM) {
2423 res = mDevice->createStream(mPreviewWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002424 params.previewWidth, params.previewHeight,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002425 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0,
2426 &mPreviewStreamId);
2427 if (res != OK) {
2428 ALOGE("%s: Camera %d: Unable to create preview stream: %s (%d)",
2429 __FUNCTION__, mCameraId, strerror(-res), res);
2430 return res;
2431 }
2432 }
2433
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07002434 res = mDevice->setStreamTransform(mPreviewStreamId,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002435 params.previewTransform);
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07002436 if (res != OK) {
2437 ALOGE("%s: Camera %d: Unable to set preview stream transform: "
2438 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2439 return res;
2440 }
2441
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002442 return OK;
2443}
2444
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002445status_t Camera2Client::updatePreviewRequest(const Parameters &params) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07002446 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002447 status_t res;
2448 if (mPreviewRequest == NULL) {
2449 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
2450 &mPreviewRequest);
2451 if (res != OK) {
2452 ALOGE("%s: Camera %d: Unable to create default preview request: "
2453 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2454 return res;
2455 }
2456 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002457
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002458 res = updateRequestCommon(mPreviewRequest, params);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002459 if (res != OK) {
2460 ALOGE("%s: Camera %d: Unable to update common entries of preview "
2461 "request: %s (%d)", __FUNCTION__, mCameraId,
2462 strerror(-res), res);
2463 return res;
2464 }
2465
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002466 return OK;
2467}
2468
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002469status_t Camera2Client::updateCaptureStream(const Parameters &params) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002470 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002471 status_t res;
2472 // Find out buffer size for JPEG
2473 camera_metadata_entry_t maxJpegSize =
2474 staticInfo(ANDROID_JPEG_MAX_SIZE);
2475 if (maxJpegSize.count == 0) {
2476 ALOGE("%s: Camera %d: Can't find ANDROID_JPEG_MAX_SIZE!",
2477 __FUNCTION__, mCameraId);
2478 return INVALID_OPERATION;
2479 }
2480
2481 if (mCaptureConsumer == 0) {
2482 // Create CPU buffer queue endpoint
2483 mCaptureConsumer = new CpuConsumer(1);
2484 mCaptureConsumer->setFrameAvailableListener(new CaptureWaiter(this));
2485 mCaptureConsumer->setName(String8("Camera2Client::CaptureConsumer"));
2486 mCaptureWindow = new SurfaceTextureClient(
2487 mCaptureConsumer->getProducerInterface());
2488 // Create memory for API consumption
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002489 mCaptureHeap = new Camera2Heap(maxJpegSize.data.i32[0], 1,
2490 "Camera2Client::CaptureHeap");
2491 if (mCaptureHeap->mHeap->getSize() == 0) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002492 ALOGE("%s: Camera %d: Unable to allocate memory for capture",
2493 __FUNCTION__, mCameraId);
2494 return NO_MEMORY;
2495 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002496 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002497
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002498 if (mCaptureStreamId != NO_STREAM) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002499 // Check if stream parameters have to change
2500 uint32_t currentWidth, currentHeight;
2501 res = mDevice->getStreamInfo(mCaptureStreamId,
2502 &currentWidth, &currentHeight, 0);
2503 if (res != OK) {
2504 ALOGE("%s: Camera %d: Error querying capture output stream info: "
2505 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2506 return res;
2507 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002508 if (currentWidth != (uint32_t)params.pictureWidth ||
2509 currentHeight != (uint32_t)params.pictureHeight) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002510 res = mDevice->deleteStream(mCaptureStreamId);
2511 if (res != OK) {
2512 ALOGE("%s: Camera %d: Unable to delete old output stream "
2513 "for capture: %s (%d)", __FUNCTION__, mCameraId,
2514 strerror(-res), res);
2515 return res;
2516 }
2517 mCaptureStreamId = NO_STREAM;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002518 }
2519 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002520
2521 if (mCaptureStreamId == NO_STREAM) {
2522 // Create stream for HAL production
2523 res = mDevice->createStream(mCaptureWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002524 params.pictureWidth, params.pictureHeight,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002525 HAL_PIXEL_FORMAT_BLOB, maxJpegSize.data.i32[0],
2526 &mCaptureStreamId);
2527 if (res != OK) {
2528 ALOGE("%s: Camera %d: Can't create output stream for capture: "
2529 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2530 return res;
2531 }
2532
2533 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002534 return OK;
2535}
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002536
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002537status_t Camera2Client::updateCaptureRequest(const Parameters &params) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002538 ATRACE_CALL();
2539 status_t res;
2540 if (mCaptureRequest == NULL) {
2541 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_STILL_CAPTURE,
2542 &mCaptureRequest);
2543 if (res != OK) {
2544 ALOGE("%s: Camera %d: Unable to create default still image request:"
2545 " %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2546 return res;
2547 }
2548 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002549
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002550 res = updateRequestCommon(mCaptureRequest, params);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002551 if (res != OK) {
2552 ALOGE("%s: Camera %d: Unable to update common entries of capture "
2553 "request: %s (%d)", __FUNCTION__, mCameraId,
2554 strerror(-res), res);
2555 return res;
2556 }
2557
2558 res = updateEntry(mCaptureRequest,
2559 ANDROID_JPEG_THUMBNAIL_SIZE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002560 params.jpegThumbSize, 2);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002561 if (res != OK) return res;
2562 res = updateEntry(mCaptureRequest,
2563 ANDROID_JPEG_THUMBNAIL_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002564 &params.jpegThumbQuality, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002565 if (res != OK) return res;
2566 res = updateEntry(mCaptureRequest,
2567 ANDROID_JPEG_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002568 &params.jpegQuality, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002569 if (res != OK) return res;
2570 res = updateEntry(mCaptureRequest,
2571 ANDROID_JPEG_ORIENTATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002572 &params.jpegRotation, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002573 if (res != OK) return res;
2574
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002575 if (params.gpsEnabled) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002576 res = updateEntry(mCaptureRequest,
2577 ANDROID_JPEG_GPS_COORDINATES,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002578 params.gpsCoordinates, 3);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002579 if (res != OK) return res;
2580 res = updateEntry(mCaptureRequest,
2581 ANDROID_JPEG_GPS_TIMESTAMP,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002582 &params.gpsTimestamp, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002583 if (res != OK) return res;
2584 res = updateEntry(mCaptureRequest,
2585 ANDROID_JPEG_GPS_PROCESSING_METHOD,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002586 params.gpsProcessingMethod.string(),
2587 params.gpsProcessingMethod.size());
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002588 if (res != OK) return res;
2589 } else {
2590 res = deleteEntry(mCaptureRequest,
2591 ANDROID_JPEG_GPS_COORDINATES);
2592 if (res != OK) return res;
2593 res = deleteEntry(mCaptureRequest,
2594 ANDROID_JPEG_GPS_TIMESTAMP);
2595 if (res != OK) return res;
2596 res = deleteEntry(mCaptureRequest,
2597 ANDROID_JPEG_GPS_PROCESSING_METHOD);
2598 if (res != OK) return res;
2599 }
2600
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002601 return OK;
2602}
2603
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002604status_t Camera2Client::updateRecordingRequest(const Parameters &params) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002605 ATRACE_CALL();
2606 status_t res;
2607 if (mRecordingRequest == NULL) {
2608 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_VIDEO_RECORD,
2609 &mRecordingRequest);
2610 if (res != OK) {
2611 ALOGE("%s: Camera %d: Unable to create default recording request:"
2612 " %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2613 return res;
2614 }
2615 }
2616
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002617 res = updateRequestCommon(mRecordingRequest, params);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002618 if (res != OK) {
2619 ALOGE("%s: Camera %d: Unable to update common entries of recording "
2620 "request: %s (%d)", __FUNCTION__, mCameraId,
2621 strerror(-res), res);
2622 return res;
2623 }
2624
2625 return OK;
2626}
2627
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002628status_t Camera2Client::updateRecordingStream(const Parameters &params) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002629 status_t res;
2630
2631 if (mRecordingConsumer == 0) {
2632 // Create CPU buffer queue endpoint
Eino-Ville Talvala803cbf62012-07-25 15:23:36 -07002633 mRecordingConsumer = new MediaConsumer(kRecordingHeapCount);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002634 mRecordingConsumer->setFrameAvailableListener(new RecordingWaiter(this));
2635 mRecordingConsumer->setName(String8("Camera2Client::RecordingConsumer"));
2636 mRecordingWindow = new SurfaceTextureClient(
2637 mRecordingConsumer->getProducerInterface());
2638 // Allocate memory later, since we don't know buffer size until receipt
2639 }
2640
2641 if (mRecordingStreamId != NO_STREAM) {
2642 // Check if stream parameters have to change
2643 uint32_t currentWidth, currentHeight;
2644 res = mDevice->getStreamInfo(mRecordingStreamId,
2645 &currentWidth, &currentHeight, 0);
2646 if (res != OK) {
2647 ALOGE("%s: Camera %d: Error querying recording output stream info: "
2648 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2649 return res;
2650 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002651 if (currentWidth != (uint32_t)params.videoWidth ||
2652 currentHeight != (uint32_t)params.videoHeight) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002653 // TODO: Should wait to be sure previous recording has finished
2654 res = mDevice->deleteStream(mRecordingStreamId);
2655 if (res != OK) {
2656 ALOGE("%s: Camera %d: Unable to delete old output stream "
2657 "for recording: %s (%d)", __FUNCTION__, mCameraId,
2658 strerror(-res), res);
2659 return res;
2660 }
2661 mRecordingStreamId = NO_STREAM;
2662 }
2663 }
2664
2665 if (mRecordingStreamId == NO_STREAM) {
2666 res = mDevice->createStream(mRecordingWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002667 params.videoWidth, params.videoHeight,
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002668 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0, &mRecordingStreamId);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002669 if (res != OK) {
2670 ALOGE("%s: Camera %d: Can't create output stream for recording: "
2671 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2672 return res;
2673 }
2674 }
2675
2676 return OK;
2677}
2678
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002679status_t Camera2Client::updateRequestCommon(camera_metadata_t *request,
2680 const Parameters &params) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002681 ATRACE_CALL();
2682 status_t res;
2683 res = updateEntry(request,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002684 ANDROID_CONTROL_AE_TARGET_FPS_RANGE, params.previewFpsRange, 2);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002685 if (res != OK) return res;
2686
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002687 uint8_t wbMode = params.autoWhiteBalanceLock ?
2688 ANDROID_CONTROL_AWB_LOCKED : params.wbMode;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002689 res = updateEntry(request,
2690 ANDROID_CONTROL_AWB_MODE, &wbMode, 1);
2691 if (res != OK) return res;
2692 res = updateEntry(request,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002693 ANDROID_CONTROL_EFFECT_MODE, &params.effectMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002694 if (res != OK) return res;
2695 res = updateEntry(request,
2696 ANDROID_CONTROL_AE_ANTIBANDING_MODE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002697 &params.antibandingMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002698 if (res != OK) return res;
2699
2700 uint8_t controlMode =
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002701 (params.sceneMode == ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED) ?
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002702 ANDROID_CONTROL_AUTO : ANDROID_CONTROL_USE_SCENE_MODE;
2703 res = updateEntry(request,
2704 ANDROID_CONTROL_MODE, &controlMode, 1);
2705 if (res != OK) return res;
2706 if (controlMode == ANDROID_CONTROL_USE_SCENE_MODE) {
2707 res = updateEntry(request,
2708 ANDROID_CONTROL_SCENE_MODE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002709 &params.sceneMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002710 if (res != OK) return res;
2711 }
2712
2713 uint8_t flashMode = ANDROID_FLASH_OFF;
2714 uint8_t aeMode;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002715 switch (params.flashMode) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002716 case Parameters::FLASH_MODE_OFF:
2717 aeMode = ANDROID_CONTROL_AE_ON; break;
2718 case Parameters::FLASH_MODE_AUTO:
2719 aeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH; break;
2720 case Parameters::FLASH_MODE_ON:
2721 aeMode = ANDROID_CONTROL_AE_ON_ALWAYS_FLASH; break;
2722 case Parameters::FLASH_MODE_TORCH:
2723 aeMode = ANDROID_CONTROL_AE_ON;
2724 flashMode = ANDROID_FLASH_TORCH;
2725 break;
2726 case Parameters::FLASH_MODE_RED_EYE:
2727 aeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE; break;
2728 default:
2729 ALOGE("%s: Camera %d: Unknown flash mode %d", __FUNCTION__,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002730 mCameraId, params.flashMode);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002731 return BAD_VALUE;
2732 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002733 if (params.autoExposureLock) aeMode = ANDROID_CONTROL_AE_LOCKED;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002734
2735 res = updateEntry(request,
2736 ANDROID_FLASH_MODE, &flashMode, 1);
2737 if (res != OK) return res;
2738 res = updateEntry(request,
2739 ANDROID_CONTROL_AE_MODE, &aeMode, 1);
2740 if (res != OK) return res;
2741
2742 float focusDistance = 0; // infinity focus in diopters
2743 uint8_t focusMode;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002744 switch (params.focusMode) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002745 case Parameters::FOCUS_MODE_AUTO:
2746 case Parameters::FOCUS_MODE_MACRO:
2747 case Parameters::FOCUS_MODE_CONTINUOUS_VIDEO:
2748 case Parameters::FOCUS_MODE_CONTINUOUS_PICTURE:
2749 case Parameters::FOCUS_MODE_EDOF:
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002750 focusMode = params.focusMode;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002751 break;
2752 case Parameters::FOCUS_MODE_INFINITY:
2753 case Parameters::FOCUS_MODE_FIXED:
2754 focusMode = ANDROID_CONTROL_AF_OFF;
2755 break;
2756 default:
2757 ALOGE("%s: Camera %d: Unknown focus mode %d", __FUNCTION__,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002758 mCameraId, params.focusMode);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002759 return BAD_VALUE;
2760 }
2761 res = updateEntry(request,
2762 ANDROID_LENS_FOCUS_DISTANCE, &focusDistance, 1);
2763 if (res != OK) return res;
2764 res = updateEntry(request,
2765 ANDROID_CONTROL_AF_MODE, &focusMode, 1);
2766 if (res != OK) return res;
2767
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002768 size_t focusingAreasSize = params.focusingAreas.size() * 5;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002769 int32_t *focusingAreas = new int32_t[focusingAreasSize];
2770 for (size_t i = 0; i < focusingAreasSize; i += 5) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002771 focusingAreas[i + 0] = params.focusingAreas[i].left;
2772 focusingAreas[i + 1] = params.focusingAreas[i].top;
2773 focusingAreas[i + 2] = params.focusingAreas[i].right;
2774 focusingAreas[i + 3] = params.focusingAreas[i].bottom;
2775 focusingAreas[i + 4] = params.focusingAreas[i].weight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002776 }
2777 res = updateEntry(request,
2778 ANDROID_CONTROL_AF_REGIONS, focusingAreas,focusingAreasSize);
2779 if (res != OK) return res;
2780 delete[] focusingAreas;
2781
2782 res = updateEntry(request,
2783 ANDROID_CONTROL_AE_EXP_COMPENSATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002784 &params.exposureCompensation, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002785 if (res != OK) return res;
2786
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002787 size_t meteringAreasSize = params.meteringAreas.size() * 5;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002788 int32_t *meteringAreas = new int32_t[meteringAreasSize];
2789 for (size_t i = 0; i < meteringAreasSize; i += 5) {
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002790 meteringAreas[i + 0] = params.meteringAreas[i].left;
2791 meteringAreas[i + 1] = params.meteringAreas[i].top;
2792 meteringAreas[i + 2] = params.meteringAreas[i].right;
2793 meteringAreas[i + 3] = params.meteringAreas[i].bottom;
2794 meteringAreas[i + 4] = params.meteringAreas[i].weight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002795 }
2796 res = updateEntry(request,
2797 ANDROID_CONTROL_AE_REGIONS, meteringAreas, meteringAreasSize);
2798 if (res != OK) return res;
2799
2800 res = updateEntry(request,
2801 ANDROID_CONTROL_AWB_REGIONS, meteringAreas, meteringAreasSize);
2802 if (res != OK) return res;
2803 delete[] meteringAreas;
2804
2805 // Need to convert zoom index into a crop rectangle. The rectangle is
2806 // chosen to maximize its area on the sensor
2807
2808 camera_metadata_entry_t maxDigitalZoom =
2809 staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM);
2810 float zoomIncrement = (maxDigitalZoom.data.f[0] - 1) /
2811 (NUM_ZOOM_STEPS-1);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002812 float zoomRatio = 1 + zoomIncrement * params.zoom;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002813
2814 camera_metadata_entry_t activePixelArraySize =
2815 staticInfo(ANDROID_SENSOR_ACTIVE_ARRAY_SIZE, 2, 2);
2816 int32_t arrayWidth = activePixelArraySize.data.i32[0];
2817 int32_t arrayHeight = activePixelArraySize.data.i32[1];
2818 float zoomLeft, zoomTop, zoomWidth, zoomHeight;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002819 if (params.previewWidth >= params.previewHeight) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002820 zoomWidth = arrayWidth / zoomRatio;
2821 zoomHeight = zoomWidth *
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002822 params.previewHeight / params.previewWidth;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002823 } else {
2824 zoomHeight = arrayHeight / zoomRatio;
2825 zoomWidth = zoomHeight *
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002826 params.previewWidth / params.previewHeight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002827 }
2828 zoomLeft = (arrayWidth - zoomWidth) / 2;
2829 zoomTop = (arrayHeight - zoomHeight) / 2;
2830
2831 int32_t cropRegion[3] = { zoomLeft, zoomTop, zoomWidth };
2832 res = updateEntry(request,
2833 ANDROID_SCALER_CROP_REGION, cropRegion, 3);
2834 if (res != OK) return res;
2835
2836 // TODO: Decide how to map recordingHint, or whether just to ignore it
2837
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002838 uint8_t vstabMode = params.videoStabilization ?
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002839 ANDROID_CONTROL_VIDEO_STABILIZATION_ON :
2840 ANDROID_CONTROL_VIDEO_STABILIZATION_OFF;
2841 res = updateEntry(request,
2842 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
2843 &vstabMode, 1);
2844 if (res != OK) return res;
2845
2846 return OK;
2847}
2848
2849status_t Camera2Client::updateEntry(camera_metadata_t *buffer,
2850 uint32_t tag, const void *data, size_t data_count) {
2851 camera_metadata_entry_t entry;
2852 status_t res;
2853 res = find_camera_metadata_entry(buffer, tag, &entry);
2854 if (res == NAME_NOT_FOUND) {
2855 res = add_camera_metadata_entry(buffer,
2856 tag, data, data_count);
2857 } else if (res == OK) {
2858 res = update_camera_metadata_entry(buffer,
2859 entry.index, data, data_count, NULL);
2860 }
2861
2862 if (res != OK) {
2863 ALOGE("%s: Unable to update metadata entry %s.%s (%x): %s (%d)",
2864 __FUNCTION__, get_camera_metadata_section_name(tag),
2865 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
2866 }
2867 return res;
2868}
2869
2870status_t Camera2Client::deleteEntry(camera_metadata_t *buffer, uint32_t tag) {
2871 camera_metadata_entry_t entry;
2872 status_t res;
2873 res = find_camera_metadata_entry(buffer, tag, &entry);
2874 if (res == NAME_NOT_FOUND) {
2875 return OK;
2876 } else if (res != OK) {
2877 ALOGE("%s: Error looking for entry %s.%s (%x): %s %d",
2878 __FUNCTION__,
2879 get_camera_metadata_section_name(tag),
2880 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
2881 return res;
2882 }
2883 res = delete_camera_metadata_entry(buffer, entry.index);
2884 if (res != OK) {
2885 ALOGE("%s: Error deleting entry %s.%s (%x): %s %d",
2886 __FUNCTION__,
2887 get_camera_metadata_section_name(tag),
2888 get_camera_metadata_tag_name(tag), tag, strerror(-res), res);
2889 }
2890 return res;
2891}
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002892
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07002893int Camera2Client::formatStringToEnum(const char *format) {
2894 return
2895 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422SP) ?
2896 HAL_PIXEL_FORMAT_YCbCr_422_SP : // NV16
2897 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420SP) ?
2898 HAL_PIXEL_FORMAT_YCrCb_420_SP : // NV21
2899 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422I) ?
2900 HAL_PIXEL_FORMAT_YCbCr_422_I : // YUY2
2901 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420P) ?
2902 HAL_PIXEL_FORMAT_YV12 : // YV12
2903 !strcmp(format, CameraParameters::PIXEL_FORMAT_RGB565) ?
2904 HAL_PIXEL_FORMAT_RGB_565 : // RGB565
2905 !strcmp(format, CameraParameters::PIXEL_FORMAT_RGBA8888) ?
2906 HAL_PIXEL_FORMAT_RGBA_8888 : // RGB8888
2907 !strcmp(format, CameraParameters::PIXEL_FORMAT_BAYER_RGGB) ?
2908 HAL_PIXEL_FORMAT_RAW_SENSOR : // Raw sensor data
2909 -1;
2910}
2911
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002912const char* Camera2Client::formatEnumToString(int format) {
2913 const char *fmt;
2914 switch(format) {
2915 case HAL_PIXEL_FORMAT_YCbCr_422_SP: // NV16
2916 fmt = CameraParameters::PIXEL_FORMAT_YUV422SP;
2917 break;
2918 case HAL_PIXEL_FORMAT_YCrCb_420_SP: // NV21
2919 fmt = CameraParameters::PIXEL_FORMAT_YUV420SP;
2920 break;
2921 case HAL_PIXEL_FORMAT_YCbCr_422_I: // YUY2
2922 fmt = CameraParameters::PIXEL_FORMAT_YUV422I;
2923 break;
2924 case HAL_PIXEL_FORMAT_YV12: // YV12
2925 fmt = CameraParameters::PIXEL_FORMAT_YUV420P;
2926 break;
2927 case HAL_PIXEL_FORMAT_RGB_565: // RGB565
2928 fmt = CameraParameters::PIXEL_FORMAT_RGB565;
2929 break;
2930 case HAL_PIXEL_FORMAT_RGBA_8888: // RGBA8888
2931 fmt = CameraParameters::PIXEL_FORMAT_RGBA8888;
2932 break;
2933 case HAL_PIXEL_FORMAT_RAW_SENSOR:
2934 ALOGW("Raw sensor preview format requested.");
2935 fmt = CameraParameters::PIXEL_FORMAT_BAYER_RGGB;
2936 break;
2937 default:
2938 ALOGE("%s: Unknown preview format: %x",
2939 __FUNCTION__, format);
2940 fmt = NULL;
2941 break;
2942 }
2943 return fmt;
2944}
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07002945
2946int Camera2Client::wbModeStringToEnum(const char *wbMode) {
2947 return
2948 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_AUTO) ?
2949 ANDROID_CONTROL_AWB_AUTO :
2950 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_INCANDESCENT) ?
2951 ANDROID_CONTROL_AWB_INCANDESCENT :
2952 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_FLUORESCENT) ?
2953 ANDROID_CONTROL_AWB_FLUORESCENT :
2954 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT) ?
2955 ANDROID_CONTROL_AWB_WARM_FLUORESCENT :
2956 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_DAYLIGHT) ?
2957 ANDROID_CONTROL_AWB_DAYLIGHT :
2958 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT) ?
2959 ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT :
2960 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_TWILIGHT) ?
2961 ANDROID_CONTROL_AWB_TWILIGHT :
2962 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_SHADE) ?
2963 ANDROID_CONTROL_AWB_SHADE :
2964 -1;
2965}
2966
2967int Camera2Client::effectModeStringToEnum(const char *effectMode) {
2968 return
2969 !strcmp(effectMode, CameraParameters::EFFECT_NONE) ?
2970 ANDROID_CONTROL_EFFECT_OFF :
2971 !strcmp(effectMode, CameraParameters::EFFECT_MONO) ?
2972 ANDROID_CONTROL_EFFECT_MONO :
2973 !strcmp(effectMode, CameraParameters::EFFECT_NEGATIVE) ?
2974 ANDROID_CONTROL_EFFECT_NEGATIVE :
2975 !strcmp(effectMode, CameraParameters::EFFECT_SOLARIZE) ?
2976 ANDROID_CONTROL_EFFECT_SOLARIZE :
2977 !strcmp(effectMode, CameraParameters::EFFECT_SEPIA) ?
2978 ANDROID_CONTROL_EFFECT_SEPIA :
2979 !strcmp(effectMode, CameraParameters::EFFECT_POSTERIZE) ?
2980 ANDROID_CONTROL_EFFECT_POSTERIZE :
2981 !strcmp(effectMode, CameraParameters::EFFECT_WHITEBOARD) ?
2982 ANDROID_CONTROL_EFFECT_WHITEBOARD :
2983 !strcmp(effectMode, CameraParameters::EFFECT_BLACKBOARD) ?
2984 ANDROID_CONTROL_EFFECT_BLACKBOARD :
2985 !strcmp(effectMode, CameraParameters::EFFECT_AQUA) ?
2986 ANDROID_CONTROL_EFFECT_AQUA :
2987 -1;
2988}
2989
2990int Camera2Client::abModeStringToEnum(const char *abMode) {
2991 return
2992 !strcmp(abMode, CameraParameters::ANTIBANDING_AUTO) ?
2993 ANDROID_CONTROL_AE_ANTIBANDING_AUTO :
2994 !strcmp(abMode, CameraParameters::ANTIBANDING_OFF) ?
2995 ANDROID_CONTROL_AE_ANTIBANDING_OFF :
2996 !strcmp(abMode, CameraParameters::ANTIBANDING_50HZ) ?
2997 ANDROID_CONTROL_AE_ANTIBANDING_50HZ :
2998 !strcmp(abMode, CameraParameters::ANTIBANDING_60HZ) ?
2999 ANDROID_CONTROL_AE_ANTIBANDING_60HZ :
3000 -1;
3001}
3002
3003int Camera2Client::sceneModeStringToEnum(const char *sceneMode) {
3004 return
3005 !strcmp(sceneMode, CameraParameters::SCENE_MODE_AUTO) ?
3006 ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED :
3007 !strcmp(sceneMode, CameraParameters::SCENE_MODE_ACTION) ?
3008 ANDROID_CONTROL_SCENE_MODE_ACTION :
3009 !strcmp(sceneMode, CameraParameters::SCENE_MODE_PORTRAIT) ?
3010 ANDROID_CONTROL_SCENE_MODE_PORTRAIT :
3011 !strcmp(sceneMode, CameraParameters::SCENE_MODE_LANDSCAPE) ?
3012 ANDROID_CONTROL_SCENE_MODE_LANDSCAPE :
3013 !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT) ?
3014 ANDROID_CONTROL_SCENE_MODE_NIGHT :
3015 !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT_PORTRAIT) ?
3016 ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT :
3017 !strcmp(sceneMode, CameraParameters::SCENE_MODE_THEATRE) ?
3018 ANDROID_CONTROL_SCENE_MODE_THEATRE :
3019 !strcmp(sceneMode, CameraParameters::SCENE_MODE_BEACH) ?
3020 ANDROID_CONTROL_SCENE_MODE_BEACH :
3021 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SNOW) ?
3022 ANDROID_CONTROL_SCENE_MODE_SNOW :
3023 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SUNSET) ?
3024 ANDROID_CONTROL_SCENE_MODE_SUNSET :
3025 !strcmp(sceneMode, CameraParameters::SCENE_MODE_STEADYPHOTO) ?
3026 ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO :
3027 !strcmp(sceneMode, CameraParameters::SCENE_MODE_FIREWORKS) ?
3028 ANDROID_CONTROL_SCENE_MODE_FIREWORKS :
3029 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SPORTS) ?
3030 ANDROID_CONTROL_SCENE_MODE_SPORTS :
3031 !strcmp(sceneMode, CameraParameters::SCENE_MODE_PARTY) ?
3032 ANDROID_CONTROL_SCENE_MODE_PARTY :
3033 !strcmp(sceneMode, CameraParameters::SCENE_MODE_CANDLELIGHT) ?
3034 ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT :
3035 !strcmp(sceneMode, CameraParameters::SCENE_MODE_BARCODE) ?
3036 ANDROID_CONTROL_SCENE_MODE_BARCODE:
3037 -1;
3038}
3039
3040Camera2Client::Parameters::flashMode_t Camera2Client::flashModeStringToEnum(
3041 const char *flashMode) {
3042 return
3043 !strcmp(flashMode, CameraParameters::FLASH_MODE_OFF) ?
3044 Parameters::FLASH_MODE_OFF :
3045 !strcmp(flashMode, CameraParameters::FLASH_MODE_AUTO) ?
3046 Parameters::FLASH_MODE_AUTO :
3047 !strcmp(flashMode, CameraParameters::FLASH_MODE_ON) ?
3048 Parameters::FLASH_MODE_ON :
3049 !strcmp(flashMode, CameraParameters::FLASH_MODE_RED_EYE) ?
3050 Parameters::FLASH_MODE_RED_EYE :
3051 !strcmp(flashMode, CameraParameters::FLASH_MODE_TORCH) ?
3052 Parameters::FLASH_MODE_TORCH :
3053 Parameters::FLASH_MODE_INVALID;
3054}
3055
3056Camera2Client::Parameters::focusMode_t Camera2Client::focusModeStringToEnum(
3057 const char *focusMode) {
3058 return
3059 !strcmp(focusMode, CameraParameters::FOCUS_MODE_AUTO) ?
3060 Parameters::FOCUS_MODE_AUTO :
3061 !strcmp(focusMode, CameraParameters::FOCUS_MODE_INFINITY) ?
3062 Parameters::FOCUS_MODE_INFINITY :
3063 !strcmp(focusMode, CameraParameters::FOCUS_MODE_MACRO) ?
3064 Parameters::FOCUS_MODE_MACRO :
3065 !strcmp(focusMode, CameraParameters::FOCUS_MODE_FIXED) ?
3066 Parameters::FOCUS_MODE_FIXED :
3067 !strcmp(focusMode, CameraParameters::FOCUS_MODE_EDOF) ?
3068 Parameters::FOCUS_MODE_EDOF :
3069 !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO) ?
3070 Parameters::FOCUS_MODE_CONTINUOUS_VIDEO :
3071 !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE) ?
3072 Parameters::FOCUS_MODE_CONTINUOUS_PICTURE :
3073 Parameters::FOCUS_MODE_INVALID;
3074}
3075
3076status_t Camera2Client::parseAreas(const char *areasCStr,
3077 Vector<Parameters::Area> *areas) {
3078 static const size_t NUM_FIELDS = 5;
3079 areas->clear();
3080 if (areasCStr == NULL) {
3081 // If no key exists, use default (0,0,0,0,0)
3082 areas->push();
3083 return OK;
3084 }
3085 String8 areasStr(areasCStr);
3086 ssize_t areaStart = areasStr.find("(", 0) + 1;
3087 while (areaStart != 0) {
3088 const char* area = areasStr.string() + areaStart;
3089 char *numEnd;
3090 int vals[NUM_FIELDS];
3091 for (size_t i = 0; i < NUM_FIELDS; i++) {
3092 errno = 0;
3093 vals[i] = strtol(area, &numEnd, 10);
3094 if (errno || numEnd == area) return BAD_VALUE;
3095 area = numEnd + 1;
3096 }
3097 areas->push(Parameters::Area(
3098 vals[0], vals[1], vals[2], vals[3], vals[4]) );
3099 areaStart = areasStr.find("(", areaStart) + 1;
3100 }
3101 return OK;
3102}
3103
3104status_t Camera2Client::validateAreas(const Vector<Parameters::Area> &areas,
3105 size_t maxRegions) {
3106 // Definition of valid area can be found in
3107 // include/camera/CameraParameters.h
3108 if (areas.size() == 0) return BAD_VALUE;
3109 if (areas.size() == 1) {
3110 if (areas[0].left == 0 &&
3111 areas[0].top == 0 &&
3112 areas[0].right == 0 &&
3113 areas[0].bottom == 0 &&
3114 areas[0].weight == 0) {
3115 // Single (0,0,0,0,0) entry is always valid (== driver decides)
3116 return OK;
3117 }
3118 }
3119 if (areas.size() > maxRegions) {
3120 ALOGE("%s: Too many areas requested: %d",
3121 __FUNCTION__, areas.size());
3122 return BAD_VALUE;
3123 }
3124
3125 for (Vector<Parameters::Area>::const_iterator a = areas.begin();
3126 a != areas.end(); a++) {
3127 if (a->weight < 1 || a->weight > 1000) return BAD_VALUE;
3128 if (a->left < -1000 || a->left > 1000) return BAD_VALUE;
3129 if (a->top < -1000 || a->top > 1000) return BAD_VALUE;
3130 if (a->right < -1000 || a->right > 1000) return BAD_VALUE;
3131 if (a->bottom < -1000 || a->bottom > 1000) return BAD_VALUE;
3132 if (a->left >= a->right) return BAD_VALUE;
3133 if (a->top >= a->bottom) return BAD_VALUE;
3134 }
3135 return OK;
3136}
3137
3138bool Camera2Client::boolFromString(const char *boolStr) {
3139 return !boolStr ? false :
3140 !strcmp(boolStr, CameraParameters::TRUE) ? true :
3141 false;
3142}
3143
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07003144int Camera2Client::degToTransform(int degrees, bool mirror) {
3145 if (!mirror) {
3146 if (degrees == 0) return 0;
3147 else if (degrees == 90) return HAL_TRANSFORM_ROT_90;
3148 else if (degrees == 180) return HAL_TRANSFORM_ROT_180;
3149 else if (degrees == 270) return HAL_TRANSFORM_ROT_270;
3150 } else { // Do mirror (horizontal flip)
3151 if (degrees == 0) { // FLIP_H and ROT_0
3152 return HAL_TRANSFORM_FLIP_H;
3153 } else if (degrees == 90) { // FLIP_H and ROT_90
3154 return HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90;
3155 } else if (degrees == 180) { // FLIP_H and ROT_180
3156 return HAL_TRANSFORM_FLIP_V;
3157 } else if (degrees == 270) { // FLIP_H and ROT_270
3158 return HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90;
3159 }
3160 }
3161 ALOGE("%s: Bad input: %d", __FUNCTION__, degrees);
3162 return -1;
3163}
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07003164
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07003165} // namespace android