blob: 05a54b7f57591e1829470a339dc36414ee33727f [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>
27
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070028#include <math.h>
29
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070030#include "Camera2Client.h"
31
32namespace android {
33
34#define ALOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__);
35#define ALOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__);
36
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070037static int getCallingPid() {
38 return IPCThreadState::self()->getCallingPid();
39}
40
41static int getCallingUid() {
42 return IPCThreadState::self()->getCallingUid();
43}
44
45// Interface used by CameraService
46
47Camera2Client::Camera2Client(const sp<CameraService>& cameraService,
48 const sp<ICameraClient>& cameraClient,
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070049 int cameraId,
50 int cameraFacing,
51 int clientPid):
52 Client(cameraService, cameraClient,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070053 cameraId, cameraFacing, clientPid),
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -070054 mState(NOT_INITIALIZED),
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -070055 mPreviewStreamId(NO_STREAM),
56 mPreviewRequest(NULL),
57 mCaptureStreamId(NO_STREAM),
58 mCaptureRequest(NULL)
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070059{
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070060 ATRACE_CALL();
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070061
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070062 mDevice = new Camera2Device(cameraId);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070063}
64
65status_t Camera2Client::initialize(camera_module_t *module)
66{
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070067 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070068 status_t res;
69
70 res = mDevice->initialize(module);
71 if (res != OK) {
72 ALOGE("%s: Camera %d: unable to initialize device: %s (%d)",
73 __FUNCTION__, mCameraId, strerror(-res), res);
74 return NO_INIT;
75 }
76
77 res = buildDefaultParameters();
78 if (res != OK) {
79 ALOGE("%s: Camera %d: unable to build defaults: %s (%d)",
80 __FUNCTION__, mCameraId, strerror(-res), res);
81 return NO_INIT;
82 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -070083
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070084 if (gLogLevel >= 1) {
85 ALOGD("%s: Default parameters converted from camera %d:", __FUNCTION__,
86 mCameraId);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -070087 ALOGD("%s", mParamsFlattened.string());
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070088 }
89
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -070090 mState = STOPPED;
91
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070092 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070093}
94
95Camera2Client::~Camera2Client() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070096 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070097 mDestructionStarted = true;
98
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070099 disconnect();
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -0700100
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700101}
102
103status_t Camera2Client::dump(int fd, const Vector<String16>& args) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700104 String8 result;
105 result.appendFormat("Client2[%d] (%p) PID: %d:\n",
106 mCameraId,
107 getCameraClient()->asBinder().get(),
108 mClientPid);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700109 result.append(" State: ");
110#define CASE_APPEND_ENUM(x) case x: result.append(#x "\n"); break;
111
112 switch (mState) {
113 CASE_APPEND_ENUM(NOT_INITIALIZED)
114 CASE_APPEND_ENUM(STOPPED)
115 CASE_APPEND_ENUM(WAITING_FOR_PREVIEW_WINDOW)
116 CASE_APPEND_ENUM(PREVIEW)
117 CASE_APPEND_ENUM(RECORD)
118 CASE_APPEND_ENUM(STILL_CAPTURE)
119 default: result.append("UNKNOWN\n"); break;
120 }
121
122 result.append(" Current parameters:\n");
123 result.appendFormat(" Preview size: %d x %d\n",
124 mParameters.previewWidth, mParameters.previewHeight);
125 result.appendFormat(" Preview FPS range: %d - %d\n",
126 mParameters.previewFpsRangeMin, mParameters.previewFpsRangeMax);
127 result.appendFormat(" Preview HAL pixel format: 0x%x\n",
128 mParameters.previewFormat);
129 result.appendFormat(" Picture size: %d x %d\n",
130 mParameters.pictureWidth, mParameters.pictureHeight);
131 result.appendFormat(" Jpeg thumbnail size: %d x %d\n",
132 mParameters.jpegThumbWidth, mParameters.jpegThumbHeight);
133 result.appendFormat(" Jpeg quality: %d, thumbnail quality: %d\n",
134 mParameters.jpegQuality, mParameters.jpegThumbQuality);
135 result.appendFormat(" Jpeg rotation: %d\n", mParameters.jpegRotation);
136 result.appendFormat(" GPS tags %s\n",
137 mParameters.gpsEnabled ? "enabled" : "disabled");
138 if (mParameters.gpsEnabled) {
139 result.appendFormat(" GPS lat x long x alt: %f x %f x %f\n",
140 mParameters.gpsLatitude, mParameters.gpsLongitude,
141 mParameters.gpsAltitude);
142 result.appendFormat(" GPS timestamp: %lld\n",
143 mParameters.gpsTimestamp);
144 result.appendFormat(" GPS processing method: %s\n",
145 mParameters.gpsProcessingMethod.string());
146 }
147
148 result.append(" White balance mode: ");
149 switch (mParameters.wbMode) {
150 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_AUTO)
151 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_INCANDESCENT)
152 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_FLUORESCENT)
153 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_WARM_FLUORESCENT)
154 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_DAYLIGHT)
155 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT)
156 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_TWILIGHT)
157 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_SHADE)
158 default: result.append("UNKNOWN\n");
159 }
160
161 result.append(" Effect mode: ");
162 switch (mParameters.effectMode) {
163 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_OFF)
164 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_MONO)
165 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_NEGATIVE)
166 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_SOLARIZE)
167 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_SEPIA)
168 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_POSTERIZE)
169 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_WHITEBOARD)
170 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_BLACKBOARD)
171 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_AQUA)
172 default: result.append("UNKNOWN\n");
173 }
174
175 result.append(" Antibanding mode: ");
176 switch (mParameters.antibandingMode) {
177 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_AUTO)
178 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_OFF)
179 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_50HZ)
180 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_60HZ)
181 default: result.append("UNKNOWN\n");
182 }
183
184 result.append(" Scene mode: ");
185 switch (mParameters.sceneMode) {
186 case ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED:
187 result.append("AUTO\n"); break;
188 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_ACTION)
189 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_PORTRAIT)
190 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_LANDSCAPE)
191 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_NIGHT)
192 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT)
193 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_THEATRE)
194 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_BEACH)
195 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SNOW)
196 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SUNSET)
197 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO)
198 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_FIREWORKS)
199 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SPORTS)
200 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_PARTY)
201 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT)
202 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_BARCODE)
203 default: result.append("UNKNOWN\n");
204 }
205
206 result.append(" Flash mode: ");
207 switch (mParameters.flashMode) {
208 CASE_APPEND_ENUM(Parameters::FLASH_MODE_OFF)
209 CASE_APPEND_ENUM(Parameters::FLASH_MODE_AUTO)
210 CASE_APPEND_ENUM(Parameters::FLASH_MODE_ON)
211 CASE_APPEND_ENUM(Parameters::FLASH_MODE_TORCH)
212 CASE_APPEND_ENUM(Parameters::FLASH_MODE_RED_EYE)
213 CASE_APPEND_ENUM(Parameters::FLASH_MODE_INVALID)
214 default: result.append("UNKNOWN\n");
215 }
216
217 result.append(" Focus mode: ");
218 switch (mParameters.focusMode) {
219 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_AUTO)
220 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_MACRO)
221 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_CONTINUOUS_VIDEO)
222 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_CONTINUOUS_PICTURE)
223 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_EDOF)
224 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_INFINITY)
225 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_FIXED)
226 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_INVALID)
227 default: result.append("UNKNOWN\n");
228 }
229
230 result.append(" Focusing areas:\n");
231 for (size_t i = 0; i < mParameters.focusingAreas.size(); i++) {
232 result.appendFormat(" [ (%d, %d, %d, %d), weight %d ]\n",
233 mParameters.focusingAreas[i].left,
234 mParameters.focusingAreas[i].top,
235 mParameters.focusingAreas[i].right,
236 mParameters.focusingAreas[i].bottom,
237 mParameters.focusingAreas[i].weight);
238 }
239
240 result.appendFormat(" Exposure compensation index: %d\n",
241 mParameters.exposureCompensation);
242
243 result.appendFormat(" AE lock %s, AWB lock %s\n",
244 mParameters.autoExposureLock ? "enabled" : "disabled",
245 mParameters.autoWhiteBalanceLock ? "enabled" : "disabled" );
246
247 result.appendFormat(" Metering areas:\n");
248 for (size_t i = 0; i < mParameters.meteringAreas.size(); i++) {
249 result.appendFormat(" [ (%d, %d, %d, %d), weight %d ]\n",
250 mParameters.meteringAreas[i].left,
251 mParameters.meteringAreas[i].top,
252 mParameters.meteringAreas[i].right,
253 mParameters.meteringAreas[i].bottom,
254 mParameters.meteringAreas[i].weight);
255 }
256
257 result.appendFormat(" Zoom index: %d\n", mParameters.zoom);
258 result.appendFormat(" Video size: %d x %d\n", mParameters.videoWidth,
259 mParameters.videoHeight);
260
261 result.appendFormat(" Recording hint is %s\n",
262 mParameters.recordingHint ? "set" : "not set");
263
264 result.appendFormat(" Video stabilization is %s\n",
265 mParameters.videoStabilization ? "enabled" : "disabled");
266
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700267 write(fd, result.string(), result.size());
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700268
269 // TODO: Dump Camera2Device
270
271#undef CASE_APPEND_ENUM
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700272 return NO_ERROR;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700273}
274
275// ICamera interface
276
277void Camera2Client::disconnect() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700278 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700279 Mutex::Autolock icl(mICameraLock);
280
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700281 if (mDevice == 0) return;
282
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700283 stopPreviewLocked();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700284
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700285 mDevice->waitUntilDrained();
286
287 if (mPreviewStreamId != NO_STREAM) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700288 mDevice->deleteStream(mPreviewStreamId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700289 mPreviewStreamId = NO_STREAM;
290 }
291
292 if (mCaptureStreamId != NO_STREAM) {
293 mDevice->deleteStream(mCaptureStreamId);
294 mCaptureStreamId = NO_STREAM;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700295 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700296
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700297 CameraService::Client::disconnect();
298}
299
300status_t Camera2Client::connect(const sp<ICameraClient>& client) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700301 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700302 Mutex::Autolock icl(mICameraLock);
303
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700304 return BAD_VALUE;
305}
306
307status_t Camera2Client::lock() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700308 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700309 Mutex::Autolock icl(mICameraLock);
310
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700311 return BAD_VALUE;
312}
313
314status_t Camera2Client::unlock() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700315 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700316 Mutex::Autolock icl(mICameraLock);
317
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700318 return BAD_VALUE;
319}
320
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700321status_t Camera2Client::setPreviewDisplay(
322 const sp<Surface>& surface) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700323 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700324 Mutex::Autolock icl(mICameraLock);
325
326 if (mState >= PREVIEW) return INVALID_OPERATION;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700327
328 sp<IBinder> binder;
329 sp<ANativeWindow> window;
330 if (surface != 0) {
331 binder = surface->asBinder();
332 window = surface;
333 }
334
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700335 return setPreviewWindowLocked(binder,window);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700336}
337
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700338status_t Camera2Client::setPreviewTexture(
339 const sp<ISurfaceTexture>& surfaceTexture) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700340 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700341 Mutex::Autolock icl(mICameraLock);
342
343 if (mState >= PREVIEW) return INVALID_OPERATION;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700344
345 sp<IBinder> binder;
346 sp<ANativeWindow> window;
347 if (surfaceTexture != 0) {
348 binder = surfaceTexture->asBinder();
349 window = new SurfaceTextureClient(surfaceTexture);
350 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700351 return setPreviewWindowLocked(binder, window);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700352}
353
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700354status_t Camera2Client::setPreviewWindowLocked(const sp<IBinder>& binder,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700355 const sp<ANativeWindow>& window) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700356 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700357 status_t res;
358
359 if (binder == mPreviewSurface) {
360 return NO_ERROR;
361 }
362
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700363 // TODO: Should wait until HAL has no remaining requests
364
365 if (mPreviewStreamId != NO_STREAM) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700366 res = mDevice->deleteStream(mPreviewStreamId);
367 if (res != OK) {
368 return res;
369 }
370 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700371 res = mDevice->createStream(window,
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -0700372 mParameters.previewWidth, mParameters.previewHeight,
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700373 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700374 &mPreviewStreamId);
375 if (res != OK) {
376 return res;
377 }
378
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700379 mPreviewSurface = binder;
380
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700381 if (mState == WAITING_FOR_PREVIEW_WINDOW) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700382 return startPreviewLocked();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700383 }
384
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700385 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700386}
387
388void Camera2Client::setPreviewCallbackFlag(int flag) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700389 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700390 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700391}
392
393status_t Camera2Client::startPreview() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700394 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700395 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700396 return startPreviewLocked();
397}
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700398
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700399status_t Camera2Client::startPreviewLocked() {
400 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700401 status_t res;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700402 if (mState >= PREVIEW) return INVALID_OPERATION;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700403
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700404 if (mPreviewStreamId == NO_STREAM) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700405 mState = WAITING_FOR_PREVIEW_WINDOW;
406 return OK;
407 }
408
409 if (mPreviewRequest == NULL) {
410 updatePreviewRequest();
411 }
412
413 uint8_t outputStream = mPreviewStreamId;
414
415 camera_metadata_entry_t outputStreams;
416 res = find_camera_metadata_entry(mPreviewRequest,
417 ANDROID_REQUEST_OUTPUT_STREAMS,
418 &outputStreams);
419 if (res == NAME_NOT_FOUND) {
420 res = add_camera_metadata_entry(mPreviewRequest,
421 ANDROID_REQUEST_OUTPUT_STREAMS,
422 &outputStream, 1);
423 } else if (res == OK) {
424 res = update_camera_metadata_entry(mPreviewRequest,
425 outputStreams.index, &outputStream, 1, NULL);
426 }
427
428 if (res != OK) {
429 ALOGE("%s: Camera %d: Unable to set up preview request: %s (%d)",
430 __FUNCTION__, mCameraId, strerror(-res), res);
431 mState = STOPPED;
432 return res;
433 }
434
435 res = mDevice->setStreamingRequest(mPreviewRequest);
436 if (res != OK) {
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700437 ALOGE("%s: Camera %d: Unable to set preview request to start preview: "
438 "%s (%d)",
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700439 __FUNCTION__, mCameraId, strerror(-res), res);
440 mState = STOPPED;
441 return res;
442 }
443 mState = PREVIEW;
444
445 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700446}
447
448void Camera2Client::stopPreview() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700449 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700450 Mutex::Autolock icl(mICameraLock);
451 stopPreviewLocked();
452}
453
454void Camera2Client::stopPreviewLocked() {
455 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700456 switch (mState) {
457 case NOT_INITIALIZED:
458 ALOGE("%s: Camera %d: Call before initialized",
459 __FUNCTION__, mCameraId);
460 break;
461 case STOPPED:
462 break;
463 case STILL_CAPTURE:
464 ALOGE("%s: Camera %d: Cannot stop preview during still capture.",
465 __FUNCTION__, mCameraId);
466 break;
467 case RECORD:
468 // TODO: Handle record stop here
469 case PREVIEW:
470 mDevice->setStreamingRequest(NULL);
471 case WAITING_FOR_PREVIEW_WINDOW:
472 mState = STOPPED;
473 break;
474 default:
475 ALOGE("%s: Camera %d: Unknown state %d", __FUNCTION__, mCameraId,
476 mState);
477 }
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700478}
479
480bool Camera2Client::previewEnabled() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700481 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700482 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700483 return mState == PREVIEW;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700484}
485
486status_t Camera2Client::storeMetaDataInBuffers(bool enabled) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700487 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700488 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700489 return BAD_VALUE;
490}
491
492status_t Camera2Client::startRecording() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700493 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700494 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700495 return BAD_VALUE;
496}
497
498void Camera2Client::stopRecording() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700499 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700500 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700501}
502
503bool Camera2Client::recordingEnabled() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700504 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700505 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700506 return BAD_VALUE;
507}
508
509void Camera2Client::releaseRecordingFrame(const sp<IMemory>& mem) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700510 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700511 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700512}
513
514status_t Camera2Client::autoFocus() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700515 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700516 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700517 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700518}
519
520status_t Camera2Client::cancelAutoFocus() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700521 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700522 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700523 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700524}
525
526status_t Camera2Client::takePicture(int msgType) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700527 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700528 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700529 status_t res;
530
531 switch (mState) {
532 case NOT_INITIALIZED:
533 case STOPPED:
534 case WAITING_FOR_PREVIEW_WINDOW:
535 ALOGE("%s: Camera %d: Cannot take picture without preview enabled",
536 __FUNCTION__, mCameraId);
537 return INVALID_OPERATION;
538 case PREVIEW:
539 case RECORD:
540 // Good to go for takePicture
541 break;
542 case STILL_CAPTURE:
543 case VIDEO_SNAPSHOT:
544 ALOGE("%s: Camera %d: Already taking a picture",
545 __FUNCTION__, mCameraId);
546 return INVALID_OPERATION;
547 }
548
549 Mutex::Autolock pl(mParamsLock);
550
551 res = updateCaptureStream();
552
553 if (mCaptureRequest == NULL) {
554 updateCaptureRequest();
555 }
556
557 // TODO: For video snapshot, need 3 streams here
558 camera_metadata_entry_t outputStreams;
559 uint8_t streamIds[2] = { mPreviewStreamId, mCaptureStreamId };
560 res = find_camera_metadata_entry(mCaptureRequest,
561 ANDROID_REQUEST_OUTPUT_STREAMS,
562 &outputStreams);
563 if (res == NAME_NOT_FOUND) {
564 res = add_camera_metadata_entry(mCaptureRequest,
565 ANDROID_REQUEST_OUTPUT_STREAMS,
566 streamIds, 2);
567 } else if (res == OK) {
568 res = update_camera_metadata_entry(mCaptureRequest,
569 outputStreams.index, streamIds, 2, NULL);
570 }
571
572 if (res != OK) {
573 ALOGE("%s: Camera %d: Unable to set up still image capture request: "
574 "%s (%d)",
575 __FUNCTION__, mCameraId, strerror(-res), res);
576 return res;
577 }
578
579 camera_metadata_t *captureCopy = clone_camera_metadata(mCaptureRequest);
580 if (captureCopy == NULL) {
581 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device",
582 __FUNCTION__, mCameraId);
583 return NO_MEMORY;
584 }
585
586 if (mState == PREVIEW) {
587 res = mDevice->setStreamingRequest(NULL);
588 if (res != OK) {
589 ALOGE("%s: Camera %d: Unable to stop preview for still capture: "
590 "%s (%d)",
591 __FUNCTION__, mCameraId, strerror(-res), res);
592 return res;
593 }
594 }
595
596 res = mDevice->capture(captureCopy);
597 if (res != OK) {
598 ALOGE("%s: Camera %d: Unable to submit still image capture request: "
599 "%s (%d)",
600 __FUNCTION__, mCameraId, strerror(-res), res);
601 return res;
602 }
603
604 switch (mState) {
605 case PREVIEW:
606 mState = STILL_CAPTURE;
607 break;
608 case RECORD:
609 mState = VIDEO_SNAPSHOT;
610 break;
611 default:
612 ALOGE("%s: Camera %d: Unknown state for still capture!",
613 __FUNCTION__, mCameraId);
614 return INVALID_OPERATION;
615 }
616
617 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700618}
619
620status_t Camera2Client::setParameters(const String8& params) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700621 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700622 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -0700623 Mutex::Autolock pl(mParamsLock);
624 status_t res;
625
626 CameraParameters newParams(params);
627
628 // TODO: Currently ignoring any changes to supposedly read-only
629 // parameters such as supported preview sizes, etc. Should probably
630 // produce an error if they're changed.
631
632 /** Extract and verify new parameters */
633
634 size_t i;
635
636 // PREVIEW_SIZE
637 int previewWidth, previewHeight;
638 newParams.getPreviewSize(&previewWidth, &previewHeight);
639
640 if (previewWidth != mParameters.previewWidth ||
641 previewHeight != mParameters.previewHeight) {
642 if (mState >= PREVIEW) {
643 ALOGE("%s: Preview size cannot be updated when preview "
644 "is active!", __FUNCTION__);
645 return BAD_VALUE;
646 }
647 camera_metadata_entry_t availablePreviewSizes =
648 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
649 for (i = 0; i < availablePreviewSizes.count; i += 2 ) {
650 if (availablePreviewSizes.data.i32[i] == previewWidth &&
651 availablePreviewSizes.data.i32[i+1] == previewHeight) break;
652 }
653 if (i == availablePreviewSizes.count) {
654 ALOGE("%s: Requested preview size %d x %d is not supported",
655 __FUNCTION__, previewWidth, previewHeight);
656 return BAD_VALUE;
657 }
658 }
659
660 // PREVIEW_FPS_RANGE
661 int previewFpsRangeMin, previewFpsRangeMax, previewFps = 0;
662 bool fpsRangeChanged = false;
663 newParams.getPreviewFpsRange(&previewFpsRangeMin, &previewFpsRangeMax);
664 if (previewFpsRangeMin != mParameters.previewFpsRangeMin ||
665 previewFpsRangeMax != mParameters.previewFpsRangeMax) {
666 fpsRangeChanged = true;
667 camera_metadata_entry_t availablePreviewFpsRanges =
668 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
669 for (i = 0; i < availablePreviewFpsRanges.count; i += 2) {
670 if ((availablePreviewFpsRanges.data.i32[i] ==
671 previewFpsRangeMin) &&
672 (availablePreviewFpsRanges.data.i32[i+1] ==
673 previewFpsRangeMax) ) {
674 break;
675 }
676 }
677 if (i == availablePreviewFpsRanges.count) {
678 ALOGE("%s: Requested preview FPS range %d - %d is not supported",
679 __FUNCTION__, previewFpsRangeMin, previewFpsRangeMax);
680 return BAD_VALUE;
681 }
682 previewFps = previewFpsRangeMin;
683 }
684
685 // PREVIEW_FORMAT
686 int previewFormat = formatStringToEnum(newParams.getPreviewFormat());
687 if (previewFormat != mParameters.previewFormat) {
688 if (mState >= PREVIEW) {
689 ALOGE("%s: Preview format cannot be updated when preview "
690 "is active!", __FUNCTION__);
691 return BAD_VALUE;
692 }
693 camera_metadata_entry_t availableFormats =
694 staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
695 for (i = 0; i < availableFormats.count; i++) {
696 if (availableFormats.data.i32[i] == previewFormat) break;
697 }
698 if (i == availableFormats.count) {
699 ALOGE("%s: Requested preview format %s (0x%x) is not supported",
700 __FUNCTION__, newParams.getPreviewFormat(), previewFormat);
701 return BAD_VALUE;
702 }
703 }
704
705 // PREVIEW_FRAME_RATE
706 // Deprecated, only use if the preview fps range is unchanged this time.
707 // The single-value FPS is the same as the minimum of the range.
708 if (!fpsRangeChanged) {
709 previewFps = newParams.getPreviewFrameRate();
710 if (previewFps != mParameters.previewFps) {
711 camera_metadata_entry_t availableFrameRates =
712 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
713 for (i = 0; i < availableFrameRates.count; i+=2) {
714 if (availableFrameRates.data.i32[i] == previewFps) break;
715 }
716 if (i == availableFrameRates.count) {
717 ALOGE("%s: Requested preview frame rate %d is not supported",
718 __FUNCTION__, previewFps);
719 return BAD_VALUE;
720 }
721 previewFpsRangeMin = availableFrameRates.data.i32[i];
722 previewFpsRangeMax = availableFrameRates.data.i32[i+1];
723 }
724 }
725
726 // PICTURE_SIZE
727 int pictureWidth, pictureHeight;
728 newParams.getPictureSize(&pictureWidth, &pictureHeight);
729 if (pictureWidth == mParameters.pictureWidth ||
730 pictureHeight == mParameters.pictureHeight) {
731 camera_metadata_entry_t availablePictureSizes =
732 staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES);
733 for (i = 0; i < availablePictureSizes.count; i+=2) {
734 if (availablePictureSizes.data.i32[i] == pictureWidth &&
735 availablePictureSizes.data.i32[i+1] == pictureHeight) break;
736 }
737 if (i == availablePictureSizes.count) {
738 ALOGE("%s: Requested picture size %d x %d is not supported",
739 __FUNCTION__, pictureWidth, pictureHeight);
740 return BAD_VALUE;
741 }
742 }
743
744 // JPEG_THUMBNAIL_WIDTH/HEIGHT
745 int jpegThumbWidth, jpegThumbHeight;
746 jpegThumbWidth =
747 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH);
748 jpegThumbHeight =
749 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT);
750 if (jpegThumbWidth != mParameters.jpegThumbWidth ||
751 jpegThumbHeight != mParameters.jpegThumbHeight) {
752 camera_metadata_entry_t availableJpegThumbSizes =
753 staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES);
754 for (i = 0; i < availableJpegThumbSizes.count; i+=2) {
755 if (availableJpegThumbSizes.data.i32[i] == jpegThumbWidth &&
756 availableJpegThumbSizes.data.i32[i+1] == jpegThumbHeight) {
757 break;
758 }
759 }
760 if (i == availableJpegThumbSizes.count) {
761 ALOGE("%s: Requested JPEG thumbnail size %d x %d is not supported",
762 __FUNCTION__, jpegThumbWidth, jpegThumbHeight);
763 return BAD_VALUE;
764 }
765 }
766
767 // JPEG_THUMBNAIL_QUALITY
768 int jpegThumbQuality =
769 newParams.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY);
770 if (jpegThumbQuality < 0 || jpegThumbQuality > 100) {
771 ALOGE("%s: Requested JPEG thumbnail quality %d is not supported",
772 __FUNCTION__, jpegThumbQuality);
773 return BAD_VALUE;
774 }
775
776 // JPEG_QUALITY
777 int jpegQuality =
778 newParams.getInt(CameraParameters::KEY_JPEG_QUALITY);
779 if (jpegQuality < 0 || jpegQuality > 100) {
780 ALOGE("%s: Requested JPEG quality %d is not supported",
781 __FUNCTION__, jpegQuality);
782 return BAD_VALUE;
783 }
784
785 // ROTATION
786 int jpegRotation =
787 newParams.getInt(CameraParameters::KEY_ROTATION);
788 if (jpegRotation != 0 &&
789 jpegRotation != 90 &&
790 jpegRotation != 180 &&
791 jpegRotation != 270) {
792 ALOGE("%s: Requested picture rotation angle %d is not supported",
793 __FUNCTION__, jpegRotation);
794 return BAD_VALUE;
795 }
796
797 // GPS
798 bool gpsEnabled = false;
799 double gpsLatitude = 0, gpsLongitude = 0, gpsAltitude = 0;
800 int64_t gpsTimestamp = 0;
801 String8 gpsProcessingMethod;
802 const char *gpsLatStr =
803 newParams.get(CameraParameters::KEY_GPS_LATITUDE);
804 if (gpsLatStr != NULL) {
805 const char *gpsLongStr =
806 newParams.get(CameraParameters::KEY_GPS_LONGITUDE);
807 const char *gpsAltitudeStr =
808 newParams.get(CameraParameters::KEY_GPS_ALTITUDE);
809 const char *gpsTimeStr =
810 newParams.get(CameraParameters::KEY_GPS_TIMESTAMP);
811 const char *gpsProcMethodStr =
812 newParams.get(CameraParameters::KEY_GPS_PROCESSING_METHOD);
813 if (gpsLongStr == NULL ||
814 gpsAltitudeStr == NULL ||
815 gpsTimeStr == NULL ||
816 gpsProcMethodStr == NULL) {
817 ALOGE("%s: Incomplete set of GPS parameters provided",
818 __FUNCTION__);
819 return BAD_VALUE;
820 }
821 char *endPtr;
822 errno = 0;
823 gpsLatitude = strtod(gpsLatStr, &endPtr);
824 if (errno || endPtr == gpsLatStr) {
825 ALOGE("%s: Malformed GPS latitude: %s", __FUNCTION__, gpsLatStr);
826 return BAD_VALUE;
827 }
828 errno = 0;
829 gpsLongitude = strtod(gpsLongStr, &endPtr);
830 if (errno || endPtr == gpsLongStr) {
831 ALOGE("%s: Malformed GPS longitude: %s", __FUNCTION__, gpsLongStr);
832 return BAD_VALUE;
833 }
834 errno = 0;
835 gpsAltitude = strtod(gpsAltitudeStr, &endPtr);
836 if (errno || endPtr == gpsAltitudeStr) {
837 ALOGE("%s: Malformed GPS altitude: %s", __FUNCTION__,
838 gpsAltitudeStr);
839 return BAD_VALUE;
840 }
841 errno = 0;
842 gpsTimestamp = strtoll(gpsTimeStr, &endPtr, 10);
843 if (errno || endPtr == gpsTimeStr) {
844 ALOGE("%s: Malformed GPS timestamp: %s", __FUNCTION__, gpsTimeStr);
845 return BAD_VALUE;
846 }
847 gpsProcessingMethod = gpsProcMethodStr;
848
849 gpsEnabled = true;
850 }
851
852 // WHITE_BALANCE
853 int wbMode = wbModeStringToEnum(
854 newParams.get(CameraParameters::KEY_WHITE_BALANCE) );
855 if (wbMode != mParameters.wbMode) {
856 camera_metadata_entry_t availableWbModes =
857 staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
858 for (i = 0; i < availableWbModes.count; i++) {
859 if (wbMode == availableWbModes.data.u8[i]) break;
860 }
861 if (i == availableWbModes.count) {
862 ALOGE("%s: Requested white balance mode %s is not supported",
863 __FUNCTION__,
864 newParams.get(CameraParameters::KEY_WHITE_BALANCE));
865 return BAD_VALUE;
866 }
867 }
868
869 // EFFECT
870 int effectMode = effectModeStringToEnum(
871 newParams.get(CameraParameters::KEY_EFFECT) );
872 if (effectMode != mParameters.effectMode) {
873 camera_metadata_entry_t availableEffectModes =
874 staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
875 for (i = 0; i < availableEffectModes.count; i++) {
876 if (effectMode == availableEffectModes.data.u8[i]) break;
877 }
878 if (i == availableEffectModes.count) {
879 ALOGE("%s: Requested effect mode \"%s\" is not supported",
880 __FUNCTION__,
881 newParams.get(CameraParameters::KEY_EFFECT) );
882 return BAD_VALUE;
883 }
884 }
885
886 // ANTIBANDING
887 int antibandingMode = abModeStringToEnum(
888 newParams.get(CameraParameters::KEY_ANTIBANDING) );
889 if (antibandingMode != mParameters.antibandingMode) {
890 camera_metadata_entry_t availableAbModes =
891 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
892 for (i = 0; i < availableAbModes.count; i++) {
893 if (antibandingMode == availableAbModes.data.u8[i]) break;
894 }
895 if (i == availableAbModes.count) {
896 ALOGE("%s: Requested antibanding mode \"%s\" is not supported",
897 __FUNCTION__,
898 newParams.get(CameraParameters::KEY_ANTIBANDING));
899 return BAD_VALUE;
900 }
901 }
902
903 // SCENE_MODE
904 int sceneMode = sceneModeStringToEnum(
905 newParams.get(CameraParameters::KEY_SCENE_MODE) );
906 if (sceneMode != mParameters.sceneMode) {
907 camera_metadata_entry_t availableSceneModes =
908 staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
909 for (i = 0; i < availableSceneModes.count; i++) {
910 if (sceneMode == availableSceneModes.data.u8[i]) break;
911 }
912 if (i == availableSceneModes.count) {
913 ALOGE("%s: Requested scene mode \"%s\" is not supported",
914 __FUNCTION__,
915 newParams.get(CameraParameters::KEY_SCENE_MODE));
916 return BAD_VALUE;
917 }
918 }
919
920 // FLASH_MODE
921 Parameters::flashMode_t flashMode = flashModeStringToEnum(
922 newParams.get(CameraParameters::KEY_FLASH_MODE) );
923 if (flashMode != mParameters.flashMode) {
924 camera_metadata_entry_t flashAvailable =
925 staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
926 if (!flashAvailable.data.u8[0] &&
927 flashMode != Parameters::FLASH_MODE_OFF) {
928 ALOGE("%s: Requested flash mode \"%s\" is not supported: "
929 "No flash on device", __FUNCTION__,
930 newParams.get(CameraParameters::KEY_FLASH_MODE));
931 return BAD_VALUE;
932 } else if (flashMode == Parameters::FLASH_MODE_RED_EYE) {
933 camera_metadata_entry_t availableAeModes =
934 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
935 for (i = 0; i < availableAeModes.count; i++) {
936 if (flashMode == availableAeModes.data.u8[i]) break;
937 }
938 if (i == availableAeModes.count) {
939 ALOGE("%s: Requested flash mode \"%s\" is not supported",
940 __FUNCTION__,
941 newParams.get(CameraParameters::KEY_FLASH_MODE));
942 return BAD_VALUE;
943 }
944 } else if (flashMode == -1) {
945 ALOGE("%s: Requested flash mode \"%s\" is unknown",
946 __FUNCTION__,
947 newParams.get(CameraParameters::KEY_FLASH_MODE));
948 return BAD_VALUE;
949 }
950 }
951
952 // FOCUS_MODE
953 Parameters::focusMode_t focusMode = focusModeStringToEnum(
954 newParams.get(CameraParameters::KEY_FOCUS_MODE));
955 if (focusMode != mParameters.focusMode) {
956 if (focusMode != Parameters::FOCUS_MODE_FIXED) {
957 camera_metadata_entry_t minFocusDistance =
958 staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE);
959 if (minFocusDistance.data.f[0] == 0) {
960 ALOGE("%s: Requested focus mode \"%s\" is not available: "
961 "fixed focus lens",
962 __FUNCTION__,
963 newParams.get(CameraParameters::KEY_FOCUS_MODE));
964 return BAD_VALUE;
965 } else if (focusMode != Parameters::FOCUS_MODE_INFINITY) {
966 camera_metadata_entry_t availableFocusModes =
967 staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
968 for (i = 0; i < availableFocusModes.count; i++) {
969 if (focusMode == availableFocusModes.data.u8[i]) break;
970 }
971 if (i == availableFocusModes.count) {
972 ALOGE("%s: Requested focus mode \"%s\" is not supported",
973 __FUNCTION__,
974 newParams.get(CameraParameters::KEY_FOCUS_MODE));
975 return BAD_VALUE;
976 }
977 }
978 }
979 }
980
981 // FOCUS_AREAS
982 Vector<Parameters::Area> focusingAreas;
983 res = parseAreas(newParams.get(CameraParameters::KEY_FOCUS_AREAS),
984 &focusingAreas);
985 size_t max3aRegions =
986 (size_t)staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1).data.i32[0];
987 if (res == OK) res = validateAreas(focusingAreas, max3aRegions);
988 if (res != OK) {
989 ALOGE("%s: Requested focus areas are malformed: %s",
990 __FUNCTION__, newParams.get(CameraParameters::KEY_FOCUS_AREAS));
991 return BAD_VALUE;
992 }
993
994 // EXPOSURE_COMPENSATION
995 int exposureCompensation =
996 newParams.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION);
997 camera_metadata_entry_t exposureCompensationRange =
998 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE);
999 if (exposureCompensation < exposureCompensationRange.data.i32[0] ||
1000 exposureCompensation > exposureCompensationRange.data.i32[1]) {
1001 ALOGE("%s: Requested exposure compensation index is out of bounds: %d",
1002 __FUNCTION__, exposureCompensation);
1003 return BAD_VALUE;
1004 }
1005
1006 // AUTO_EXPOSURE_LOCK (always supported)
1007 bool autoExposureLock = boolFromString(
1008 newParams.get(CameraParameters::KEY_AUTO_EXPOSURE_LOCK));
1009
1010 // AUTO_WHITEBALANCE_LOCK (always supported)
1011 bool autoWhiteBalanceLock = boolFromString(
1012 newParams.get(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK));
1013
1014 // METERING_AREAS
1015 Vector<Parameters::Area> meteringAreas;
1016 res = parseAreas(newParams.get(CameraParameters::KEY_METERING_AREAS),
1017 &meteringAreas);
1018 if (res == OK) res = validateAreas(focusingAreas, max3aRegions);
1019 if (res != OK) {
1020 ALOGE("%s: Requested metering areas are malformed: %s",
1021 __FUNCTION__,
1022 newParams.get(CameraParameters::KEY_METERING_AREAS));
1023 return BAD_VALUE;
1024 }
1025
1026 // ZOOM
1027 int zoom = newParams.getInt(CameraParameters::KEY_ZOOM);
1028 if (zoom < 0 || zoom > (int)NUM_ZOOM_STEPS) {
1029 ALOGE("%s: Requested zoom level %d is not supported",
1030 __FUNCTION__, zoom);
1031 return BAD_VALUE;
1032 }
1033
1034 // VIDEO_SIZE
1035 int videoWidth, videoHeight;
1036 newParams.getVideoSize(&videoWidth, &videoHeight);
1037 if (videoWidth != mParameters.videoWidth ||
1038 videoHeight != mParameters.videoHeight) {
1039 if (mState == RECORD) {
1040 ALOGE("%s: Video size cannot be updated when recording is active!",
1041 __FUNCTION__);
1042 return BAD_VALUE;
1043 }
1044 camera_metadata_entry_t availableVideoSizes =
1045 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
1046 for (i = 0; i < availableVideoSizes.count; i += 2 ) {
1047 if (availableVideoSizes.data.i32[i] == videoWidth &&
1048 availableVideoSizes.data.i32[i+1] == videoHeight) break;
1049 }
1050 if (i == availableVideoSizes.count) {
1051 ALOGE("%s: Requested video size %d x %d is not supported",
1052 __FUNCTION__, videoWidth, videoHeight);
1053 return BAD_VALUE;
1054 }
1055 }
1056
1057 // RECORDING_HINT (always supported)
1058 bool recordingHint = boolFromString(
1059 newParams.get(CameraParameters::KEY_RECORDING_HINT) );
1060
1061 // VIDEO_STABILIZATION
1062 bool videoStabilization = boolFromString(
1063 newParams.get(CameraParameters::KEY_VIDEO_STABILIZATION) );
1064 camera_metadata_entry_t availableVideoStabilizationModes =
1065 staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
1066 if (videoStabilization && availableVideoStabilizationModes.count == 1) {
1067 ALOGE("%s: Video stabilization not supported", __FUNCTION__);
1068 }
1069
1070 /** Update internal parameters */
1071 mParameters.previewWidth = previewWidth;
1072 mParameters.previewHeight = previewHeight;
1073 mParameters.previewFpsRangeMin = previewFpsRangeMin;
1074 mParameters.previewFpsRangeMax = previewFpsRangeMax;
1075 mParameters.previewFps = previewFps;
1076 mParameters.previewFormat = previewFormat;
1077
1078 mParameters.pictureWidth = pictureWidth;
1079 mParameters.pictureHeight = pictureHeight;
1080
1081 mParameters.jpegThumbWidth = jpegThumbWidth;
1082 mParameters.jpegThumbHeight = jpegThumbHeight;
1083 mParameters.jpegQuality = jpegQuality;
1084 mParameters.jpegThumbQuality = jpegThumbQuality;
1085
1086 mParameters.gpsEnabled = gpsEnabled;
1087 mParameters.gpsLatitude = gpsLatitude;
1088 mParameters.gpsLongitude = gpsLongitude;
1089 mParameters.gpsAltitude = gpsAltitude;
1090 mParameters.gpsTimestamp = gpsTimestamp;
1091 mParameters.gpsProcessingMethod = gpsProcessingMethod;
1092
1093 mParameters.wbMode = wbMode;
1094 mParameters.effectMode = effectMode;
1095 mParameters.antibandingMode = antibandingMode;
1096 mParameters.sceneMode = sceneMode;
1097
1098 mParameters.flashMode = flashMode;
1099 mParameters.focusMode = focusMode;
1100
1101 mParameters.focusingAreas = focusingAreas;
1102 mParameters.exposureCompensation = exposureCompensation;
1103 mParameters.autoExposureLock = autoExposureLock;
1104 mParameters.autoWhiteBalanceLock = autoWhiteBalanceLock;
1105 mParameters.meteringAreas = meteringAreas;
1106 mParameters.zoom = zoom;
1107
1108 mParameters.videoWidth = videoWidth;
1109 mParameters.videoHeight = videoHeight;
1110
1111 mParameters.recordingHint = recordingHint;
1112 mParameters.videoStabilization = videoStabilization;
1113
1114 updatePreviewRequest();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001115 updateCaptureRequest();
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001116
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001117 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001118}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001119
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001120String8 Camera2Client::getParameters() const {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001121 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001122 Mutex::Autolock icl(mICameraLock);
1123
1124 Mutex::Autolock pl(mParamsLock);
1125
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001126 // TODO: Deal with focus distances
1127 return mParamsFlattened;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001128}
1129
1130status_t Camera2Client::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001131 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001132 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001133 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001134}
1135
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001136/** Device-related methods */
1137
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001138void Camera2Client::onCaptureAvailable() {
1139 ATRACE_CALL();
1140 status_t res;
1141 sp<ICameraClient> currentClient;
1142 CpuConsumer::LockedBuffer imgBuffer;
1143 {
1144 Mutex::Autolock icl(mICameraLock);
1145
1146 // TODO: Signal errors here upstream
1147 if (mState != STILL_CAPTURE && mState != VIDEO_SNAPSHOT) {
1148 ALOGE("%s: Camera %d: Still image produced unexpectedly!",
1149 __FUNCTION__, mCameraId);
1150 return;
1151 }
1152
1153 res = mCaptureConsumer->lockNextBuffer(&imgBuffer);
1154 if (res != OK) {
1155 ALOGE("%s: Camera %d: Error receiving still image buffer: %s (%d)",
1156 __FUNCTION__, mCameraId, strerror(-res), res);
1157 return;
1158 }
1159
1160 if (imgBuffer.format != HAL_PIXEL_FORMAT_BLOB) {
1161 ALOGE("%s: Camera %d: Unexpected format for still image: "
1162 "%x, expected %x", __FUNCTION__, mCameraId,
1163 imgBuffer.format,
1164 HAL_PIXEL_FORMAT_BLOB);
1165 mCaptureConsumer->unlockBuffer(imgBuffer);
1166 return;
1167 }
1168
1169 // TODO: Optimize this to avoid memcopy
1170 void* captureMemory = mCaptureHeap->getBase();
1171 size_t size = mCaptureHeap->getSize();
1172 memcpy(captureMemory, imgBuffer.data, size);
1173
1174 mCaptureConsumer->unlockBuffer(imgBuffer);
1175
1176 currentClient = mCameraClient;
1177 switch (mState) {
1178 case STILL_CAPTURE:
1179 mState = STOPPED;
1180 break;
1181 case VIDEO_SNAPSHOT:
1182 mState = RECORD;
1183 break;
1184 default:
1185 ALOGE("%s: Camera %d: Unexpected state %d", __FUNCTION__,
1186 mCameraId, mState);
1187 break;
1188 }
1189 }
1190 // Call outside mICameraLock to allow re-entrancy from notification
1191 if (currentClient != 0) {
1192 currentClient->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE,
1193 mCaptureMemory, NULL);
1194 }
1195}
1196
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001197camera_metadata_entry_t Camera2Client::staticInfo(uint32_t tag,
1198 size_t minCount, size_t maxCount) {
1199 status_t res;
1200 camera_metadata_entry_t entry;
1201 res = find_camera_metadata_entry(mDevice->info(),
1202 tag,
1203 &entry);
1204 if (CC_UNLIKELY( res != OK )) {
1205 const char* tagSection = get_camera_metadata_section_name(tag);
1206 if (tagSection == NULL) tagSection = "<unknown>";
1207 const char* tagName = get_camera_metadata_tag_name(tag);
1208 if (tagName == NULL) tagName = "<unknown>";
1209
1210 ALOGE("Error finding static metadata entry '%s.%s' (%x): %s (%d)",
1211 tagSection, tagName, tag, strerror(-res), res);
1212 entry.count = 0;
1213 entry.data.u8 = NULL;
1214 } else if (CC_UNLIKELY(
1215 (minCount != 0 && entry.count < minCount) ||
1216 (maxCount != 0 && entry.count > maxCount) ) ) {
1217 const char* tagSection = get_camera_metadata_section_name(tag);
1218 if (tagSection == NULL) tagSection = "<unknown>";
1219 const char* tagName = get_camera_metadata_tag_name(tag);
1220 if (tagName == NULL) tagName = "<unknown>";
1221 ALOGE("Malformed static metadata entry '%s.%s' (%x):"
1222 "Expected between %d and %d values, but got %d values",
1223 tagSection, tagName, tag, minCount, maxCount, entry.count);
1224 entry.count = 0;
1225 entry.data.u8 = NULL;
1226 }
1227
1228 return entry;
1229}
1230
1231/** Utility methods */
1232
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001233
1234status_t Camera2Client::buildDefaultParameters() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001235 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001236 Mutex::Autolock pl(mParamsLock);
1237
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001238 status_t res;
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001239 CameraParameters params;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001240
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001241 camera_metadata_entry_t availableProcessedSizes =
1242 staticInfo(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES, 2);
1243 if (!availableProcessedSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001244
1245 // TODO: Pick more intelligently
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001246 mParameters.previewWidth = availableProcessedSizes.data.i32[0];
1247 mParameters.previewHeight = availableProcessedSizes.data.i32[1];
1248 mParameters.videoWidth = mParameters.previewWidth;
1249 mParameters.videoHeight = mParameters.previewHeight;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001250
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001251 params.setPreviewSize(mParameters.previewWidth, mParameters.previewHeight);
1252 params.setVideoSize(mParameters.videoWidth, mParameters.videoHeight);
1253 params.set(CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO,
1254 String8::format("%dx%d",
1255 mParameters.previewWidth, mParameters.previewHeight));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001256 {
1257 String8 supportedPreviewSizes;
1258 for (size_t i=0; i < availableProcessedSizes.count; i += 2) {
1259 if (i != 0) supportedPreviewSizes += ",";
1260 supportedPreviewSizes += String8::format("%dx%d",
1261 availableProcessedSizes.data.i32[i],
1262 availableProcessedSizes.data.i32[i+1]);
1263 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001264 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001265 supportedPreviewSizes);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001266 params.set(CameraParameters::KEY_SUPPORTED_VIDEO_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001267 supportedPreviewSizes);
1268 }
1269
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001270 camera_metadata_entry_t availableFpsRanges =
1271 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
1272 if (!availableFpsRanges.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001273
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001274 mParameters.previewFpsRangeMin = availableFpsRanges.data.i32[0];
1275 mParameters.previewFpsRangeMax = availableFpsRanges.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001276
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001277 params.set(CameraParameters::KEY_PREVIEW_FPS_RANGE,
1278 String8::format("%d,%d",
1279 mParameters.previewFpsRangeMin,
1280 mParameters.previewFpsRangeMax));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001281
1282 {
1283 String8 supportedPreviewFpsRange;
1284 for (size_t i=0; i < availableFpsRanges.count; i += 2) {
1285 if (i != 0) supportedPreviewFpsRange += ",";
1286 supportedPreviewFpsRange += String8::format("(%d,%d)",
1287 availableFpsRanges.data.i32[i],
1288 availableFpsRanges.data.i32[i+1]);
1289 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001290 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001291 supportedPreviewFpsRange);
1292 }
1293
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001294 mParameters.previewFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
1295 params.set(CameraParameters::KEY_PREVIEW_FORMAT,
1296 formatEnumToString(mParameters.previewFormat)); // NV21
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001297
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001298 camera_metadata_entry_t availableFormats =
1299 staticInfo(ANDROID_SCALER_AVAILABLE_FORMATS);
1300
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001301 {
1302 String8 supportedPreviewFormats;
1303 bool addComma = false;
1304 for (size_t i=0; i < availableFormats.count; i++) {
1305 if (addComma) supportedPreviewFormats += ",";
1306 addComma = true;
1307 switch (availableFormats.data.i32[i]) {
1308 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001309 supportedPreviewFormats +=
1310 CameraParameters::PIXEL_FORMAT_YUV422SP;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001311 break;
1312 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001313 supportedPreviewFormats +=
1314 CameraParameters::PIXEL_FORMAT_YUV420SP;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001315 break;
1316 case HAL_PIXEL_FORMAT_YCbCr_422_I:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001317 supportedPreviewFormats +=
1318 CameraParameters::PIXEL_FORMAT_YUV422I;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001319 break;
1320 case HAL_PIXEL_FORMAT_YV12:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001321 supportedPreviewFormats +=
1322 CameraParameters::PIXEL_FORMAT_YUV420P;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001323 break;
1324 case HAL_PIXEL_FORMAT_RGB_565:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001325 supportedPreviewFormats +=
1326 CameraParameters::PIXEL_FORMAT_RGB565;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001327 break;
1328 // Not advertizing JPEG, RAW_SENSOR, etc, for preview formats
1329 case HAL_PIXEL_FORMAT_RAW_SENSOR:
1330 addComma = false;
1331 break;
1332 default:
1333 ALOGW("%s: Camera %d: Unknown preview format: %x",
1334 __FUNCTION__, mCameraId, availableFormats.data.i32[i]);
1335 addComma = false;
1336 break;
1337 }
1338 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001339 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001340 supportedPreviewFormats);
1341 }
1342
1343 // PREVIEW_FRAME_RATE / SUPPORTED_PREVIEW_FRAME_RATES are deprecated, but
1344 // still have to do something sane for them
1345
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001346 params.set(CameraParameters::KEY_PREVIEW_FRAME_RATE,
1347 mParameters.previewFpsRangeMin);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001348
1349 {
1350 String8 supportedPreviewFrameRates;
1351 for (size_t i=0; i < availableFpsRanges.count; i += 2) {
1352 if (i != 0) supportedPreviewFrameRates += ",";
1353 supportedPreviewFrameRates += String8::format("%d",
1354 availableFpsRanges.data.i32[i]);
1355 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001356 params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001357 supportedPreviewFrameRates);
1358 }
1359
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001360 camera_metadata_entry_t availableJpegSizes =
1361 staticInfo(ANDROID_SCALER_AVAILABLE_JPEG_SIZES, 2);
1362 if (!availableJpegSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001363
1364 // TODO: Pick maximum
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001365 mParameters.pictureWidth = availableJpegSizes.data.i32[0];
1366 mParameters.pictureHeight = availableJpegSizes.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001367
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001368 params.setPictureSize(mParameters.pictureWidth,
1369 mParameters.pictureHeight);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001370
1371 {
1372 String8 supportedPictureSizes;
1373 for (size_t i=0; i < availableJpegSizes.count; i += 2) {
1374 if (i != 0) supportedPictureSizes += ",";
1375 supportedPictureSizes += String8::format("%dx%d",
1376 availableJpegSizes.data.i32[i],
1377 availableJpegSizes.data.i32[i+1]);
1378 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001379 params.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001380 supportedPictureSizes);
1381 }
1382
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001383 params.setPictureFormat(CameraParameters::PIXEL_FORMAT_JPEG);
1384 params.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS,
1385 CameraParameters::PIXEL_FORMAT_JPEG);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001386
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001387 camera_metadata_entry_t availableJpegThumbnailSizes =
1388 staticInfo(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES, 2);
1389 if (!availableJpegThumbnailSizes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001390
1391 // TODO: Pick default thumbnail size sensibly
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001392 mParameters.jpegThumbWidth = availableJpegThumbnailSizes.data.i32[0];
1393 mParameters.jpegThumbHeight = availableJpegThumbnailSizes.data.i32[1];
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001394
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001395 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH,
1396 mParameters.jpegThumbWidth);
1397 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT,
1398 mParameters.jpegThumbHeight);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001399
1400 {
1401 String8 supportedJpegThumbSizes;
1402 for (size_t i=0; i < availableJpegThumbnailSizes.count; i += 2) {
1403 if (i != 0) supportedJpegThumbSizes += ",";
1404 supportedJpegThumbSizes += String8::format("%dx%d",
1405 availableJpegThumbnailSizes.data.i32[i],
1406 availableJpegThumbnailSizes.data.i32[i+1]);
1407 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001408 params.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001409 supportedJpegThumbSizes);
1410 }
1411
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001412 mParameters.jpegThumbQuality = 90;
1413 params.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY,
1414 mParameters.jpegThumbQuality);
1415 mParameters.jpegQuality = 90;
1416 params.set(CameraParameters::KEY_JPEG_QUALITY,
1417 mParameters.jpegQuality);
1418 mParameters.jpegRotation = 0;
1419 params.set(CameraParameters::KEY_ROTATION,
1420 mParameters.jpegRotation);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001421
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001422 mParameters.gpsEnabled = false;
1423 mParameters.gpsProcessingMethod = "unknown";
1424 // GPS fields in CameraParameters are not set by implementation
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001425
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001426 mParameters.wbMode = ANDROID_CONTROL_AWB_AUTO;
1427 params.set(CameraParameters::KEY_WHITE_BALANCE,
1428 CameraParameters::WHITE_BALANCE_AUTO);
1429
1430 camera_metadata_entry_t availableWhiteBalanceModes =
1431 staticInfo(ANDROID_CONTROL_AWB_AVAILABLE_MODES);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001432 {
1433 String8 supportedWhiteBalance;
1434 bool addComma = false;
1435 for (size_t i=0; i < availableWhiteBalanceModes.count; i++) {
1436 if (addComma) supportedWhiteBalance += ",";
1437 addComma = true;
1438 switch (availableWhiteBalanceModes.data.u8[i]) {
1439 case ANDROID_CONTROL_AWB_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001440 supportedWhiteBalance +=
1441 CameraParameters::WHITE_BALANCE_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001442 break;
1443 case ANDROID_CONTROL_AWB_INCANDESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001444 supportedWhiteBalance +=
1445 CameraParameters::WHITE_BALANCE_INCANDESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001446 break;
1447 case ANDROID_CONTROL_AWB_FLUORESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001448 supportedWhiteBalance +=
1449 CameraParameters::WHITE_BALANCE_FLUORESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001450 break;
1451 case ANDROID_CONTROL_AWB_WARM_FLUORESCENT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001452 supportedWhiteBalance +=
1453 CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001454 break;
1455 case ANDROID_CONTROL_AWB_DAYLIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001456 supportedWhiteBalance +=
1457 CameraParameters::WHITE_BALANCE_DAYLIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001458 break;
1459 case ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001460 supportedWhiteBalance +=
1461 CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001462 break;
1463 case ANDROID_CONTROL_AWB_TWILIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001464 supportedWhiteBalance +=
1465 CameraParameters::WHITE_BALANCE_TWILIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001466 break;
1467 case ANDROID_CONTROL_AWB_SHADE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001468 supportedWhiteBalance +=
1469 CameraParameters::WHITE_BALANCE_SHADE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001470 break;
1471 // Skipping values not mappable to v1 API
1472 case ANDROID_CONTROL_AWB_OFF:
1473 addComma = false;
1474 break;
1475 default:
1476 ALOGW("%s: Camera %d: Unknown white balance value: %d",
1477 __FUNCTION__, mCameraId,
1478 availableWhiteBalanceModes.data.u8[i]);
1479 addComma = false;
1480 break;
1481 }
1482 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001483 params.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001484 supportedWhiteBalance);
1485 }
1486
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001487 mParameters.effectMode = ANDROID_CONTROL_EFFECT_OFF;
1488 params.set(CameraParameters::KEY_EFFECT,
1489 CameraParameters::EFFECT_NONE);
1490
1491 camera_metadata_entry_t availableEffects =
1492 staticInfo(ANDROID_CONTROL_AVAILABLE_EFFECTS);
1493 if (!availableEffects.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001494 {
1495 String8 supportedEffects;
1496 bool addComma = false;
1497 for (size_t i=0; i < availableEffects.count; i++) {
1498 if (addComma) supportedEffects += ",";
1499 addComma = true;
1500 switch (availableEffects.data.u8[i]) {
1501 case ANDROID_CONTROL_EFFECT_OFF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001502 supportedEffects +=
1503 CameraParameters::EFFECT_NONE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001504 break;
1505 case ANDROID_CONTROL_EFFECT_MONO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001506 supportedEffects +=
1507 CameraParameters::EFFECT_MONO;
1508 break;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001509 case ANDROID_CONTROL_EFFECT_NEGATIVE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001510 supportedEffects +=
1511 CameraParameters::EFFECT_NEGATIVE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001512 break;
1513 case ANDROID_CONTROL_EFFECT_SOLARIZE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001514 supportedEffects +=
1515 CameraParameters::EFFECT_SOLARIZE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001516 break;
1517 case ANDROID_CONTROL_EFFECT_SEPIA:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001518 supportedEffects +=
1519 CameraParameters::EFFECT_SEPIA;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001520 break;
1521 case ANDROID_CONTROL_EFFECT_POSTERIZE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001522 supportedEffects +=
1523 CameraParameters::EFFECT_POSTERIZE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001524 break;
1525 case ANDROID_CONTROL_EFFECT_WHITEBOARD:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001526 supportedEffects +=
1527 CameraParameters::EFFECT_WHITEBOARD;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001528 break;
1529 case ANDROID_CONTROL_EFFECT_BLACKBOARD:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001530 supportedEffects +=
1531 CameraParameters::EFFECT_BLACKBOARD;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001532 break;
1533 case ANDROID_CONTROL_EFFECT_AQUA:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001534 supportedEffects +=
1535 CameraParameters::EFFECT_AQUA;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001536 break;
1537 default:
1538 ALOGW("%s: Camera %d: Unknown effect value: %d",
1539 __FUNCTION__, mCameraId, availableEffects.data.u8[i]);
1540 addComma = false;
1541 break;
1542 }
1543 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001544 params.set(CameraParameters::KEY_SUPPORTED_EFFECTS, supportedEffects);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001545 }
1546
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001547 mParameters.antibandingMode = ANDROID_CONTROL_AE_ANTIBANDING_AUTO;
1548 params.set(CameraParameters::KEY_ANTIBANDING,
1549 CameraParameters::ANTIBANDING_AUTO);
1550
1551 camera_metadata_entry_t availableAntibandingModes =
1552 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES);
1553 if (!availableAntibandingModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001554 {
1555 String8 supportedAntibanding;
1556 bool addComma = false;
1557 for (size_t i=0; i < availableAntibandingModes.count; i++) {
1558 if (addComma) supportedAntibanding += ",";
1559 addComma = true;
1560 switch (availableAntibandingModes.data.u8[i]) {
1561 case ANDROID_CONTROL_AE_ANTIBANDING_OFF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001562 supportedAntibanding +=
1563 CameraParameters::ANTIBANDING_OFF;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001564 break;
1565 case ANDROID_CONTROL_AE_ANTIBANDING_50HZ:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001566 supportedAntibanding +=
1567 CameraParameters::ANTIBANDING_50HZ;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001568 break;
1569 case ANDROID_CONTROL_AE_ANTIBANDING_60HZ:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001570 supportedAntibanding +=
1571 CameraParameters::ANTIBANDING_60HZ;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001572 break;
1573 case ANDROID_CONTROL_AE_ANTIBANDING_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001574 supportedAntibanding +=
1575 CameraParameters::ANTIBANDING_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001576 break;
1577 default:
1578 ALOGW("%s: Camera %d: Unknown antibanding value: %d",
1579 __FUNCTION__, mCameraId,
1580 availableAntibandingModes.data.u8[i]);
1581 addComma = false;
1582 break;
1583 }
1584 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001585 params.set(CameraParameters::KEY_SUPPORTED_ANTIBANDING,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001586 supportedAntibanding);
1587 }
1588
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001589 mParameters.sceneMode = ANDROID_CONTROL_OFF;
1590 params.set(CameraParameters::KEY_SCENE_MODE,
1591 CameraParameters::SCENE_MODE_AUTO);
1592
1593 camera_metadata_entry_t availableSceneModes =
1594 staticInfo(ANDROID_CONTROL_AVAILABLE_SCENE_MODES);
1595 if (!availableSceneModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001596 {
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001597 String8 supportedSceneModes(CameraParameters::SCENE_MODE_AUTO);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001598 bool addComma = true;
1599 bool noSceneModes = false;
1600 for (size_t i=0; i < availableSceneModes.count; i++) {
1601 if (addComma) supportedSceneModes += ",";
1602 addComma = true;
1603 switch (availableSceneModes.data.u8[i]) {
1604 case ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED:
1605 noSceneModes = true;
1606 break;
1607 case ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY:
1608 // Not in old API
1609 addComma = false;
1610 break;
1611 case ANDROID_CONTROL_SCENE_MODE_ACTION:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001612 supportedSceneModes +=
1613 CameraParameters::SCENE_MODE_ACTION;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001614 break;
1615 case ANDROID_CONTROL_SCENE_MODE_PORTRAIT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001616 supportedSceneModes +=
1617 CameraParameters::SCENE_MODE_PORTRAIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001618 break;
1619 case ANDROID_CONTROL_SCENE_MODE_LANDSCAPE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001620 supportedSceneModes +=
1621 CameraParameters::SCENE_MODE_LANDSCAPE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001622 break;
1623 case ANDROID_CONTROL_SCENE_MODE_NIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001624 supportedSceneModes +=
1625 CameraParameters::SCENE_MODE_NIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001626 break;
1627 case ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001628 supportedSceneModes +=
1629 CameraParameters::SCENE_MODE_NIGHT_PORTRAIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001630 break;
1631 case ANDROID_CONTROL_SCENE_MODE_THEATRE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001632 supportedSceneModes +=
1633 CameraParameters::SCENE_MODE_THEATRE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001634 break;
1635 case ANDROID_CONTROL_SCENE_MODE_BEACH:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001636 supportedSceneModes +=
1637 CameraParameters::SCENE_MODE_BEACH;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001638 break;
1639 case ANDROID_CONTROL_SCENE_MODE_SNOW:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001640 supportedSceneModes +=
1641 CameraParameters::SCENE_MODE_SNOW;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001642 break;
1643 case ANDROID_CONTROL_SCENE_MODE_SUNSET:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001644 supportedSceneModes +=
1645 CameraParameters::SCENE_MODE_SUNSET;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001646 break;
1647 case ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001648 supportedSceneModes +=
1649 CameraParameters::SCENE_MODE_STEADYPHOTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001650 break;
1651 case ANDROID_CONTROL_SCENE_MODE_FIREWORKS:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001652 supportedSceneModes +=
1653 CameraParameters::SCENE_MODE_FIREWORKS;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001654 break;
1655 case ANDROID_CONTROL_SCENE_MODE_SPORTS:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001656 supportedSceneModes +=
1657 CameraParameters::SCENE_MODE_SPORTS;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001658 break;
1659 case ANDROID_CONTROL_SCENE_MODE_PARTY:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001660 supportedSceneModes +=
1661 CameraParameters::SCENE_MODE_PARTY;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001662 break;
1663 case ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001664 supportedSceneModes +=
1665 CameraParameters::SCENE_MODE_CANDLELIGHT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001666 break;
1667 case ANDROID_CONTROL_SCENE_MODE_BARCODE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001668 supportedSceneModes +=
1669 CameraParameters::SCENE_MODE_BARCODE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001670 break;
1671 default:
1672 ALOGW("%s: Camera %d: Unknown scene mode value: %d",
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001673 __FUNCTION__, mCameraId,
1674 availableSceneModes.data.u8[i]);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001675 addComma = false;
1676 break;
1677 }
1678 }
1679 if (!noSceneModes) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001680 params.set(CameraParameters::KEY_SUPPORTED_SCENE_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001681 supportedSceneModes);
1682 }
1683 }
1684
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001685 camera_metadata_entry_t flashAvailable =
1686 staticInfo(ANDROID_FLASH_AVAILABLE, 1, 1);
1687 if (!flashAvailable.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001688
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001689 camera_metadata_entry_t availableAeModes =
1690 staticInfo(ANDROID_CONTROL_AE_AVAILABLE_MODES);
1691 if (!availableAeModes.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001692
1693 if (flashAvailable.data.u8[0]) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001694 mParameters.flashMode = Parameters::FLASH_MODE_AUTO;
1695 params.set(CameraParameters::KEY_FLASH_MODE,
1696 CameraParameters::FLASH_MODE_AUTO);
1697
1698 String8 supportedFlashModes(CameraParameters::FLASH_MODE_OFF);
1699 supportedFlashModes = supportedFlashModes +
1700 "," + CameraParameters::FLASH_MODE_AUTO +
1701 "," + CameraParameters::FLASH_MODE_ON +
1702 "," + CameraParameters::FLASH_MODE_TORCH;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001703 for (size_t i=0; i < availableAeModes.count; i++) {
1704 if (availableAeModes.data.u8[i] ==
1705 ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001706 supportedFlashModes = supportedFlashModes + "," +
1707 CameraParameters::FLASH_MODE_RED_EYE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001708 break;
1709 }
1710 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001711 params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001712 supportedFlashModes);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001713 } else {
1714 mParameters.flashMode = Parameters::FLASH_MODE_OFF;
1715 params.set(CameraParameters::KEY_FLASH_MODE,
1716 CameraParameters::FLASH_MODE_OFF);
1717 params.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
1718 CameraParameters::FLASH_MODE_OFF);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001719 }
1720
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001721 camera_metadata_entry_t minFocusDistance =
1722 staticInfo(ANDROID_LENS_MINIMUM_FOCUS_DISTANCE, 1, 1);
1723 if (!minFocusDistance.count) return NO_INIT;
1724
1725 camera_metadata_entry_t availableAfModes =
1726 staticInfo(ANDROID_CONTROL_AF_AVAILABLE_MODES);
1727 if (!availableAfModes.count) return NO_INIT;
1728
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001729 if (minFocusDistance.data.f[0] == 0) {
1730 // Fixed-focus lens
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001731 mParameters.focusMode = Parameters::FOCUS_MODE_FIXED;
1732 params.set(CameraParameters::KEY_FOCUS_MODE,
1733 CameraParameters::FOCUS_MODE_FIXED);
1734 params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
1735 CameraParameters::FOCUS_MODE_FIXED);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001736 } else {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001737 mParameters.focusMode = Parameters::FOCUS_MODE_AUTO;
1738 params.set(CameraParameters::KEY_FOCUS_MODE,
1739 CameraParameters::FOCUS_MODE_AUTO);
1740 String8 supportedFocusModes(CameraParameters::FOCUS_MODE_FIXED);
1741 supportedFocusModes = supportedFocusModes + "," +
1742 CameraParameters::FOCUS_MODE_INFINITY;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001743 bool addComma = true;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001744
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001745 for (size_t i=0; i < availableAfModes.count; i++) {
1746 if (addComma) supportedFocusModes += ",";
1747 addComma = true;
1748 switch (availableAfModes.data.u8[i]) {
1749 case ANDROID_CONTROL_AF_AUTO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001750 supportedFocusModes +=
1751 CameraParameters::FOCUS_MODE_AUTO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001752 break;
1753 case ANDROID_CONTROL_AF_MACRO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001754 supportedFocusModes +=
1755 CameraParameters::FOCUS_MODE_MACRO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001756 break;
1757 case ANDROID_CONTROL_AF_CONTINUOUS_VIDEO:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001758 supportedFocusModes +=
1759 CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001760 break;
1761 case ANDROID_CONTROL_AF_CONTINUOUS_PICTURE:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001762 supportedFocusModes +=
1763 CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001764 break;
1765 case ANDROID_CONTROL_AF_EDOF:
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001766 supportedFocusModes +=
1767 CameraParameters::FOCUS_MODE_EDOF;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001768 break;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -07001769 // Not supported in old API
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001770 case ANDROID_CONTROL_AF_OFF:
1771 addComma = false;
1772 break;
1773 default:
1774 ALOGW("%s: Camera %d: Unknown AF mode value: %d",
1775 __FUNCTION__, mCameraId, availableAfModes.data.u8[i]);
1776 addComma = false;
1777 break;
1778 }
1779 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001780 params.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001781 supportedFocusModes);
1782 }
1783
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001784 camera_metadata_entry_t max3aRegions =
1785 staticInfo(ANDROID_CONTROL_MAX_REGIONS, 1, 1);
1786 if (!max3aRegions.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001787
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001788 params.set(CameraParameters::KEY_MAX_NUM_FOCUS_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001789 max3aRegions.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001790 params.set(CameraParameters::KEY_FOCUS_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001791 "(0,0,0,0,0)");
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001792 mParameters.focusingAreas.clear();
1793 mParameters.focusingAreas.add(Parameters::Area(0,0,0,0,0));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001794
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001795 camera_metadata_entry_t availableFocalLengths =
1796 staticInfo(ANDROID_LENS_AVAILABLE_FOCAL_LENGTHS);
1797 if (!availableFocalLengths.count) return NO_INIT;
1798
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001799 float minFocalLength = availableFocalLengths.data.f[0];
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001800 params.setFloat(CameraParameters::KEY_FOCAL_LENGTH, minFocalLength);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001801
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001802 camera_metadata_entry_t sensorSize =
1803 staticInfo(ANDROID_SENSOR_PHYSICAL_SIZE, 2, 2);
1804 if (!sensorSize.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001805
1806 // The fields of view here assume infinity focus, maximum wide angle
1807 float horizFov = 180 / M_PI *
1808 2 * atanf(sensorSize.data.f[0] / (2 * minFocalLength));
1809 float vertFov = 180 / M_PI *
1810 2 * atanf(sensorSize.data.f[1] / (2 * minFocalLength));
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001811 params.setFloat(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, horizFov);
1812 params.setFloat(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, vertFov);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001813
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001814 mParameters.exposureCompensation = 0;
1815 params.set(CameraParameters::KEY_EXPOSURE_COMPENSATION,
1816 mParameters.exposureCompensation);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001817
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001818 camera_metadata_entry_t exposureCompensationRange =
1819 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_RANGE, 2, 2);
1820 if (!exposureCompensationRange.count) return NO_INIT;
1821
1822 params.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001823 exposureCompensationRange.data.i32[1]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001824 params.set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001825 exposureCompensationRange.data.i32[0]);
1826
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001827 camera_metadata_entry_t exposureCompensationStep =
1828 staticInfo(ANDROID_CONTROL_AE_EXP_COMPENSATION_STEP, 1, 1);
1829 if (!exposureCompensationStep.count) return NO_INIT;
1830
1831 params.setFloat(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001832 exposureCompensationStep.data.r[0].numerator /
1833 exposureCompensationStep.data.r[0].denominator);
1834
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001835 mParameters.autoExposureLock = false;
1836 params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK,
1837 CameraParameters::FALSE);
1838 params.set(CameraParameters::KEY_AUTO_EXPOSURE_LOCK_SUPPORTED,
1839 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001840
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001841 mParameters.autoWhiteBalanceLock = false;
1842 params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK,
1843 CameraParameters::FALSE);
1844 params.set(CameraParameters::KEY_AUTO_WHITEBALANCE_LOCK_SUPPORTED,
1845 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001846
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001847 mParameters.meteringAreas.add(Parameters::Area(0, 0, 0, 0, 0));
1848 params.set(CameraParameters::KEY_MAX_NUM_METERING_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001849 max3aRegions.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001850 params.set(CameraParameters::KEY_METERING_AREAS,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001851 "(0,0,0,0,0)");
1852
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001853 mParameters.zoom = 0;
1854 params.set(CameraParameters::KEY_ZOOM, mParameters.zoom);
1855 params.set(CameraParameters::KEY_MAX_ZOOM, NUM_ZOOM_STEPS - 1);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001856
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001857 camera_metadata_entry_t maxDigitalZoom =
1858 staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM, 1, 1);
1859 if (!maxDigitalZoom.count) return NO_INIT;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001860
1861 {
1862 String8 zoomRatios;
1863 float zoom = 1.f;
1864 float zoomIncrement = (maxDigitalZoom.data.f[0] - zoom) /
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001865 (NUM_ZOOM_STEPS-1);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001866 bool addComma = false;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001867 for (size_t i=0; i < NUM_ZOOM_STEPS; i++) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001868 if (addComma) zoomRatios += ",";
1869 addComma = true;
1870 zoomRatios += String8::format("%d", static_cast<int>(zoom * 100));
1871 zoom += zoomIncrement;
1872 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001873 params.set(CameraParameters::KEY_ZOOM_RATIOS, zoomRatios);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001874 }
1875
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001876 params.set(CameraParameters::KEY_ZOOM_SUPPORTED,
1877 CameraParameters::TRUE);
1878 params.set(CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED,
1879 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001880
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001881 params.set(CameraParameters::KEY_FOCUS_DISTANCES,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001882 "Infinity,Infinity,Infinity");
1883
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001884 camera_metadata_entry_t maxFacesDetected =
1885 staticInfo(ANDROID_STATS_MAX_FACE_COUNT, 1, 1);
1886 params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001887 maxFacesDetected.data.i32[0]);
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001888 params.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001889 0);
1890
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001891 params.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT,
1892 formatEnumToString(HAL_PIXEL_FORMAT_YCrCb_420_SP));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001893
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001894 params.set(CameraParameters::KEY_RECORDING_HINT,
1895 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001896
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001897 params.set(CameraParameters::KEY_VIDEO_SNAPSHOT_SUPPORTED,
1898 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001899
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001900 params.set(CameraParameters::KEY_VIDEO_STABILIZATION,
1901 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001902
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001903 camera_metadata_entry_t availableVideoStabilizationModes =
1904 staticInfo(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
1905 if (!availableVideoStabilizationModes.count) return NO_INIT;
1906
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001907 if (availableVideoStabilizationModes.count > 1) {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001908 params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
1909 CameraParameters::TRUE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001910 } else {
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001911 params.set(CameraParameters::KEY_VIDEO_STABILIZATION_SUPPORTED,
1912 CameraParameters::FALSE);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001913 }
1914
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001915 mParamsFlattened = params.flatten();
1916
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001917 return OK;
1918}
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001919
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001920status_t Camera2Client::updatePreviewRequest() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001921 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001922 status_t res;
1923 if (mPreviewRequest == NULL) {
1924 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
1925 &mPreviewRequest);
1926 if (res != OK) {
1927 ALOGE("%s: Camera %d: Unable to create default preview request: "
1928 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
1929 return res;
1930 }
1931 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001932 // TODO: Adjust for params changes
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001933 return OK;
1934}
1935
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001936status_t Camera2Client::updateCaptureStream() {
1937 status_t res;
1938 // Find out buffer size for JPEG
1939 camera_metadata_entry_t maxJpegSize =
1940 staticInfo(ANDROID_JPEG_MAX_SIZE);
1941 if (maxJpegSize.count == 0) {
1942 ALOGE("%s: Camera %d: Can't find ANDROID_JPEG_MAX_SIZE!",
1943 __FUNCTION__, mCameraId);
1944 return INVALID_OPERATION;
1945 }
1946
1947 if (mCaptureConsumer == 0) {
1948 // Create CPU buffer queue endpoint
1949 mCaptureConsumer = new CpuConsumer(1);
1950 mCaptureConsumer->setFrameAvailableListener(new CaptureWaiter(this));
1951 mCaptureConsumer->setName(String8("Camera2Client::CaptureConsumer"));
1952 mCaptureWindow = new SurfaceTextureClient(
1953 mCaptureConsumer->getProducerInterface());
1954 // Create memory for API consumption
1955 mCaptureHeap = new MemoryHeapBase(maxJpegSize.data.i32[0], 0,
1956 "Camera2Client::CaptureHeap");
1957 if (mCaptureHeap->getSize() == 0) {
1958 ALOGE("%s: Camera %d: Unable to allocate memory for capture",
1959 __FUNCTION__, mCameraId);
1960 return NO_MEMORY;
1961 }
1962 mCaptureMemory = new MemoryBase(mCaptureHeap,
1963 0, maxJpegSize.data.i32[0]);
1964 }
1965 if (mCaptureStreamId == NO_STREAM) {
1966 // Create stream for HAL production
1967 res = mDevice->createStream(mCaptureWindow,
1968 mParameters.pictureWidth, mParameters.pictureHeight,
1969 HAL_PIXEL_FORMAT_BLOB, maxJpegSize.data.i32[0],
1970 &mCaptureStreamId);
1971 if (res != OK) {
1972 ALOGE("%s: Camera %d: Can't create output stream for capture: "
1973 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
1974 return res;
1975 }
1976
1977 } else {
1978 // Check if stream parameters have to change
1979 uint32_t currentWidth, currentHeight;
1980 res = mDevice->getStreamInfo(mCaptureStreamId,
1981 &currentWidth, &currentHeight, 0);
1982 if (res != OK) {
1983 ALOGE("%s: Camera %d: Error querying capture output stream info: "
1984 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
1985 return res;
1986 }
1987 if (currentWidth != (uint32_t)mParameters.pictureWidth ||
1988 currentHeight != (uint32_t)mParameters.pictureHeight) {
1989 res = mDevice->deleteStream(mCaptureStreamId);
1990 if (res != OK) {
1991 ALOGE("%s: Camera %d: Unable to delete old output stream "
1992 "for capture: %s (%d)", __FUNCTION__, mCameraId,
1993 strerror(-res), res);
1994 return res;
1995 }
1996 mCaptureStreamId = NO_STREAM;
1997 return updateCaptureStream();
1998 }
1999 }
2000 return OK;
2001}
2002status_t Camera2Client::updateCaptureRequest() {
2003 ATRACE_CALL();
2004 status_t res;
2005 if (mCaptureRequest == NULL) {
2006 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_STILL_CAPTURE,
2007 &mCaptureRequest);
2008 if (res != OK) {
2009 ALOGE("%s: Camera %d: Unable to create default still image request:"
2010 " %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2011 return res;
2012 }
2013 }
2014 // TODO: Adjust for params changes
2015 return OK;
2016}
2017
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07002018int Camera2Client::formatStringToEnum(const char *format) {
2019 return
2020 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422SP) ?
2021 HAL_PIXEL_FORMAT_YCbCr_422_SP : // NV16
2022 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420SP) ?
2023 HAL_PIXEL_FORMAT_YCrCb_420_SP : // NV21
2024 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV422I) ?
2025 HAL_PIXEL_FORMAT_YCbCr_422_I : // YUY2
2026 !strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420P) ?
2027 HAL_PIXEL_FORMAT_YV12 : // YV12
2028 !strcmp(format, CameraParameters::PIXEL_FORMAT_RGB565) ?
2029 HAL_PIXEL_FORMAT_RGB_565 : // RGB565
2030 !strcmp(format, CameraParameters::PIXEL_FORMAT_RGBA8888) ?
2031 HAL_PIXEL_FORMAT_RGBA_8888 : // RGB8888
2032 !strcmp(format, CameraParameters::PIXEL_FORMAT_BAYER_RGGB) ?
2033 HAL_PIXEL_FORMAT_RAW_SENSOR : // Raw sensor data
2034 -1;
2035}
2036
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07002037const char* Camera2Client::formatEnumToString(int format) {
2038 const char *fmt;
2039 switch(format) {
2040 case HAL_PIXEL_FORMAT_YCbCr_422_SP: // NV16
2041 fmt = CameraParameters::PIXEL_FORMAT_YUV422SP;
2042 break;
2043 case HAL_PIXEL_FORMAT_YCrCb_420_SP: // NV21
2044 fmt = CameraParameters::PIXEL_FORMAT_YUV420SP;
2045 break;
2046 case HAL_PIXEL_FORMAT_YCbCr_422_I: // YUY2
2047 fmt = CameraParameters::PIXEL_FORMAT_YUV422I;
2048 break;
2049 case HAL_PIXEL_FORMAT_YV12: // YV12
2050 fmt = CameraParameters::PIXEL_FORMAT_YUV420P;
2051 break;
2052 case HAL_PIXEL_FORMAT_RGB_565: // RGB565
2053 fmt = CameraParameters::PIXEL_FORMAT_RGB565;
2054 break;
2055 case HAL_PIXEL_FORMAT_RGBA_8888: // RGBA8888
2056 fmt = CameraParameters::PIXEL_FORMAT_RGBA8888;
2057 break;
2058 case HAL_PIXEL_FORMAT_RAW_SENSOR:
2059 ALOGW("Raw sensor preview format requested.");
2060 fmt = CameraParameters::PIXEL_FORMAT_BAYER_RGGB;
2061 break;
2062 default:
2063 ALOGE("%s: Unknown preview format: %x",
2064 __FUNCTION__, format);
2065 fmt = NULL;
2066 break;
2067 }
2068 return fmt;
2069}
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07002070
2071int Camera2Client::wbModeStringToEnum(const char *wbMode) {
2072 return
2073 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_AUTO) ?
2074 ANDROID_CONTROL_AWB_AUTO :
2075 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_INCANDESCENT) ?
2076 ANDROID_CONTROL_AWB_INCANDESCENT :
2077 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_FLUORESCENT) ?
2078 ANDROID_CONTROL_AWB_FLUORESCENT :
2079 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT) ?
2080 ANDROID_CONTROL_AWB_WARM_FLUORESCENT :
2081 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_DAYLIGHT) ?
2082 ANDROID_CONTROL_AWB_DAYLIGHT :
2083 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT) ?
2084 ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT :
2085 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_TWILIGHT) ?
2086 ANDROID_CONTROL_AWB_TWILIGHT :
2087 !strcmp(wbMode, CameraParameters::WHITE_BALANCE_SHADE) ?
2088 ANDROID_CONTROL_AWB_SHADE :
2089 -1;
2090}
2091
2092int Camera2Client::effectModeStringToEnum(const char *effectMode) {
2093 return
2094 !strcmp(effectMode, CameraParameters::EFFECT_NONE) ?
2095 ANDROID_CONTROL_EFFECT_OFF :
2096 !strcmp(effectMode, CameraParameters::EFFECT_MONO) ?
2097 ANDROID_CONTROL_EFFECT_MONO :
2098 !strcmp(effectMode, CameraParameters::EFFECT_NEGATIVE) ?
2099 ANDROID_CONTROL_EFFECT_NEGATIVE :
2100 !strcmp(effectMode, CameraParameters::EFFECT_SOLARIZE) ?
2101 ANDROID_CONTROL_EFFECT_SOLARIZE :
2102 !strcmp(effectMode, CameraParameters::EFFECT_SEPIA) ?
2103 ANDROID_CONTROL_EFFECT_SEPIA :
2104 !strcmp(effectMode, CameraParameters::EFFECT_POSTERIZE) ?
2105 ANDROID_CONTROL_EFFECT_POSTERIZE :
2106 !strcmp(effectMode, CameraParameters::EFFECT_WHITEBOARD) ?
2107 ANDROID_CONTROL_EFFECT_WHITEBOARD :
2108 !strcmp(effectMode, CameraParameters::EFFECT_BLACKBOARD) ?
2109 ANDROID_CONTROL_EFFECT_BLACKBOARD :
2110 !strcmp(effectMode, CameraParameters::EFFECT_AQUA) ?
2111 ANDROID_CONTROL_EFFECT_AQUA :
2112 -1;
2113}
2114
2115int Camera2Client::abModeStringToEnum(const char *abMode) {
2116 return
2117 !strcmp(abMode, CameraParameters::ANTIBANDING_AUTO) ?
2118 ANDROID_CONTROL_AE_ANTIBANDING_AUTO :
2119 !strcmp(abMode, CameraParameters::ANTIBANDING_OFF) ?
2120 ANDROID_CONTROL_AE_ANTIBANDING_OFF :
2121 !strcmp(abMode, CameraParameters::ANTIBANDING_50HZ) ?
2122 ANDROID_CONTROL_AE_ANTIBANDING_50HZ :
2123 !strcmp(abMode, CameraParameters::ANTIBANDING_60HZ) ?
2124 ANDROID_CONTROL_AE_ANTIBANDING_60HZ :
2125 -1;
2126}
2127
2128int Camera2Client::sceneModeStringToEnum(const char *sceneMode) {
2129 return
2130 !strcmp(sceneMode, CameraParameters::SCENE_MODE_AUTO) ?
2131 ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED :
2132 !strcmp(sceneMode, CameraParameters::SCENE_MODE_ACTION) ?
2133 ANDROID_CONTROL_SCENE_MODE_ACTION :
2134 !strcmp(sceneMode, CameraParameters::SCENE_MODE_PORTRAIT) ?
2135 ANDROID_CONTROL_SCENE_MODE_PORTRAIT :
2136 !strcmp(sceneMode, CameraParameters::SCENE_MODE_LANDSCAPE) ?
2137 ANDROID_CONTROL_SCENE_MODE_LANDSCAPE :
2138 !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT) ?
2139 ANDROID_CONTROL_SCENE_MODE_NIGHT :
2140 !strcmp(sceneMode, CameraParameters::SCENE_MODE_NIGHT_PORTRAIT) ?
2141 ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT :
2142 !strcmp(sceneMode, CameraParameters::SCENE_MODE_THEATRE) ?
2143 ANDROID_CONTROL_SCENE_MODE_THEATRE :
2144 !strcmp(sceneMode, CameraParameters::SCENE_MODE_BEACH) ?
2145 ANDROID_CONTROL_SCENE_MODE_BEACH :
2146 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SNOW) ?
2147 ANDROID_CONTROL_SCENE_MODE_SNOW :
2148 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SUNSET) ?
2149 ANDROID_CONTROL_SCENE_MODE_SUNSET :
2150 !strcmp(sceneMode, CameraParameters::SCENE_MODE_STEADYPHOTO) ?
2151 ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO :
2152 !strcmp(sceneMode, CameraParameters::SCENE_MODE_FIREWORKS) ?
2153 ANDROID_CONTROL_SCENE_MODE_FIREWORKS :
2154 !strcmp(sceneMode, CameraParameters::SCENE_MODE_SPORTS) ?
2155 ANDROID_CONTROL_SCENE_MODE_SPORTS :
2156 !strcmp(sceneMode, CameraParameters::SCENE_MODE_PARTY) ?
2157 ANDROID_CONTROL_SCENE_MODE_PARTY :
2158 !strcmp(sceneMode, CameraParameters::SCENE_MODE_CANDLELIGHT) ?
2159 ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT :
2160 !strcmp(sceneMode, CameraParameters::SCENE_MODE_BARCODE) ?
2161 ANDROID_CONTROL_SCENE_MODE_BARCODE:
2162 -1;
2163}
2164
2165Camera2Client::Parameters::flashMode_t Camera2Client::flashModeStringToEnum(
2166 const char *flashMode) {
2167 return
2168 !strcmp(flashMode, CameraParameters::FLASH_MODE_OFF) ?
2169 Parameters::FLASH_MODE_OFF :
2170 !strcmp(flashMode, CameraParameters::FLASH_MODE_AUTO) ?
2171 Parameters::FLASH_MODE_AUTO :
2172 !strcmp(flashMode, CameraParameters::FLASH_MODE_ON) ?
2173 Parameters::FLASH_MODE_ON :
2174 !strcmp(flashMode, CameraParameters::FLASH_MODE_RED_EYE) ?
2175 Parameters::FLASH_MODE_RED_EYE :
2176 !strcmp(flashMode, CameraParameters::FLASH_MODE_TORCH) ?
2177 Parameters::FLASH_MODE_TORCH :
2178 Parameters::FLASH_MODE_INVALID;
2179}
2180
2181Camera2Client::Parameters::focusMode_t Camera2Client::focusModeStringToEnum(
2182 const char *focusMode) {
2183 return
2184 !strcmp(focusMode, CameraParameters::FOCUS_MODE_AUTO) ?
2185 Parameters::FOCUS_MODE_AUTO :
2186 !strcmp(focusMode, CameraParameters::FOCUS_MODE_INFINITY) ?
2187 Parameters::FOCUS_MODE_INFINITY :
2188 !strcmp(focusMode, CameraParameters::FOCUS_MODE_MACRO) ?
2189 Parameters::FOCUS_MODE_MACRO :
2190 !strcmp(focusMode, CameraParameters::FOCUS_MODE_FIXED) ?
2191 Parameters::FOCUS_MODE_FIXED :
2192 !strcmp(focusMode, CameraParameters::FOCUS_MODE_EDOF) ?
2193 Parameters::FOCUS_MODE_EDOF :
2194 !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO) ?
2195 Parameters::FOCUS_MODE_CONTINUOUS_VIDEO :
2196 !strcmp(focusMode, CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE) ?
2197 Parameters::FOCUS_MODE_CONTINUOUS_PICTURE :
2198 Parameters::FOCUS_MODE_INVALID;
2199}
2200
2201status_t Camera2Client::parseAreas(const char *areasCStr,
2202 Vector<Parameters::Area> *areas) {
2203 static const size_t NUM_FIELDS = 5;
2204 areas->clear();
2205 if (areasCStr == NULL) {
2206 // If no key exists, use default (0,0,0,0,0)
2207 areas->push();
2208 return OK;
2209 }
2210 String8 areasStr(areasCStr);
2211 ssize_t areaStart = areasStr.find("(", 0) + 1;
2212 while (areaStart != 0) {
2213 const char* area = areasStr.string() + areaStart;
2214 char *numEnd;
2215 int vals[NUM_FIELDS];
2216 for (size_t i = 0; i < NUM_FIELDS; i++) {
2217 errno = 0;
2218 vals[i] = strtol(area, &numEnd, 10);
2219 if (errno || numEnd == area) return BAD_VALUE;
2220 area = numEnd + 1;
2221 }
2222 areas->push(Parameters::Area(
2223 vals[0], vals[1], vals[2], vals[3], vals[4]) );
2224 areaStart = areasStr.find("(", areaStart) + 1;
2225 }
2226 return OK;
2227}
2228
2229status_t Camera2Client::validateAreas(const Vector<Parameters::Area> &areas,
2230 size_t maxRegions) {
2231 // Definition of valid area can be found in
2232 // include/camera/CameraParameters.h
2233 if (areas.size() == 0) return BAD_VALUE;
2234 if (areas.size() == 1) {
2235 if (areas[0].left == 0 &&
2236 areas[0].top == 0 &&
2237 areas[0].right == 0 &&
2238 areas[0].bottom == 0 &&
2239 areas[0].weight == 0) {
2240 // Single (0,0,0,0,0) entry is always valid (== driver decides)
2241 return OK;
2242 }
2243 }
2244 if (areas.size() > maxRegions) {
2245 ALOGE("%s: Too many areas requested: %d",
2246 __FUNCTION__, areas.size());
2247 return BAD_VALUE;
2248 }
2249
2250 for (Vector<Parameters::Area>::const_iterator a = areas.begin();
2251 a != areas.end(); a++) {
2252 if (a->weight < 1 || a->weight > 1000) return BAD_VALUE;
2253 if (a->left < -1000 || a->left > 1000) return BAD_VALUE;
2254 if (a->top < -1000 || a->top > 1000) return BAD_VALUE;
2255 if (a->right < -1000 || a->right > 1000) return BAD_VALUE;
2256 if (a->bottom < -1000 || a->bottom > 1000) return BAD_VALUE;
2257 if (a->left >= a->right) return BAD_VALUE;
2258 if (a->top >= a->bottom) return BAD_VALUE;
2259 }
2260 return OK;
2261}
2262
2263bool Camera2Client::boolFromString(const char *boolStr) {
2264 return !boolStr ? false :
2265 !strcmp(boolStr, CameraParameters::TRUE) ? true :
2266 false;
2267}
2268
2269
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07002270} // namespace android