blob: acd290dbc1892681448e2fffd79f2ac13bdf7019 [file] [log] [blame]
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "Camera2Client"
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070018#define ATRACE_TAG ATRACE_TAG_CAMERA
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070019//#define LOG_NDEBUG 0
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070020
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070021#include <utils/Log.h>
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070022#include <utils/Trace.h>
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070023
24#include <cutils/properties.h>
25#include <gui/SurfaceTextureClient.h>
26#include <gui/Surface.h>
Eino-Ville Talvala78822d72012-07-18 17:52:18 -070027#include <media/hardware/MetadataBufferType.h>
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070028
29#include "Camera2Client.h"
30
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070031#define ALOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__);
32#define ALOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__);
33
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -070034namespace android {
35
36using namespace camera2;
37
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070038static int getCallingPid() {
39 return IPCThreadState::self()->getCallingPid();
40}
41
42static int getCallingUid() {
43 return IPCThreadState::self()->getCallingUid();
44}
45
46// Interface used by CameraService
47
48Camera2Client::Camera2Client(const sp<CameraService>& cameraService,
49 const sp<ICameraClient>& cameraClient,
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070050 int cameraId,
51 int cameraFacing,
52 int clientPid):
53 Client(cameraService, cameraClient,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070054 cameraId, cameraFacing, clientPid),
Eino-Ville Talvalaea0d51b2012-08-28 01:25:43 -070055 mSharedCameraClient(cameraClient),
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -070056 mParameters(cameraId, cameraFacing),
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -070057 mPreviewStreamId(NO_STREAM),
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -070058 mRecordingStreamId(NO_STREAM),
James Dong983cf232012-08-01 16:39:55 -070059 mRecordingHeapCount(kDefaultRecordingHeapCount)
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070060{
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070061 ATRACE_CALL();
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -070062 ALOGV("%s: Created client for camera %d", __FUNCTION__, cameraId);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070063
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070064 mDevice = new Camera2Device(cameraId);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -070065
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -070066 SharedParameters::Lock l(mParameters);
67 l.mParameters.state = Parameters::DISCONNECTED;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070068}
69
Eino-Ville Talvala3a609142012-07-31 14:36:26 -070070status_t Camera2Client::checkPid(const char* checkLocation) const {
71 int callingPid = getCallingPid();
72 if (callingPid == mClientPid) return NO_ERROR;
73
74 ALOGE("%s: attempt to use a locked camera from a different process"
75 " (old pid %d, new pid %d)", checkLocation, mClientPid, callingPid);
76 return PERMISSION_DENIED;
77}
78
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070079status_t Camera2Client::initialize(camera_module_t *module)
80{
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070081 ATRACE_CALL();
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -070082 ALOGV("%s: Initializing client for camera %d", __FUNCTION__, mCameraId);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070083 status_t res;
84
85 res = mDevice->initialize(module);
86 if (res != OK) {
87 ALOGE("%s: Camera %d: unable to initialize device: %s (%d)",
88 __FUNCTION__, mCameraId, strerror(-res), res);
89 return NO_INIT;
90 }
91
Eino-Ville Talvala174181e2012-08-03 13:53:39 -070092 res = mDevice->setNotifyCallback(this);
93
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -070094 SharedParameters::Lock l(mParameters);
95
96 res = l.mParameters.initialize(&(mDevice->info()));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070097 if (res != OK) {
98 ALOGE("%s: Camera %d: unable to build defaults: %s (%d)",
99 __FUNCTION__, mCameraId, strerror(-res), res);
100 return NO_INIT;
101 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -0700102
Eino-Ville Talvalaea0d51b2012-08-28 01:25:43 -0700103 mFrameProcessor = new FrameProcessor(this);
104 String8 frameThreadName = String8::format("Camera2Client[%d]::FrameProcessor",
105 mCameraId);
106 mFrameProcessor->run(frameThreadName.string());
107
108 mCaptureProcessor = new CaptureProcessor(this);
109 String8 captureThreadName =
110 String8::format("Camera2Client[%d]::CaptureProcessor", mCameraId);
111 mCaptureProcessor->run(captureThreadName.string());
112
Eino-Ville Talvalad86a6882012-08-28 11:34:14 -0700113 mCallbackProcessor = new CallbackProcessor(this);
114 String8 callbackThreadName =
115 String8::format("Camera2Client[%d]::CallbackProcessor", mCameraId);
116 mCallbackProcessor->run(callbackThreadName.string());
117
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700118 if (gLogLevel >= 1) {
119 ALOGD("%s: Default parameters converted from camera %d:", __FUNCTION__,
120 mCameraId);
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700121 ALOGD("%s", l.mParameters.paramsFlattened.string());
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700122 }
123
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700124 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700125}
126
127Camera2Client::~Camera2Client() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700128 ATRACE_CALL();
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -0700129 ALOGV("%s: Camera %d: Shutting down client.", __FUNCTION__, mCameraId);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700130
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700131 mDestructionStarted = true;
132
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700133 // Rewrite mClientPid to allow shutdown by CameraService
134 mClientPid = getCallingPid();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700135 disconnect();
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -0700136
137 mFrameProcessor->requestExit();
138 ALOGV("%s: Camera %d: Shutdown complete", __FUNCTION__, mCameraId);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700139}
140
141status_t Camera2Client::dump(int fd, const Vector<String16>& args) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700142 String8 result;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700143 result.appendFormat("Client2[%d] (%p) PID: %d, dump:\n",
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700144 mCameraId,
145 getCameraClient()->asBinder().get(),
146 mClientPid);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700147 result.append(" State: ");
148#define CASE_APPEND_ENUM(x) case x: result.append(#x "\n"); break;
149
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700150 const Parameters& p = mParameters.unsafeAccess();
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700151
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700152 result.append(Parameters::getStateName(p.state));
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700153
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700154 result.append("\n Current parameters:\n");
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700155 result.appendFormat(" Preview size: %d x %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700156 p.previewWidth, p.previewHeight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700157 result.appendFormat(" Preview FPS range: %d - %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700158 p.previewFpsRange[0], p.previewFpsRange[1]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700159 result.appendFormat(" Preview HAL pixel format: 0x%x\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700160 p.previewFormat);
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700161 result.appendFormat(" Preview transform: %x\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700162 p.previewTransform);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700163 result.appendFormat(" Picture size: %d x %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700164 p.pictureWidth, p.pictureHeight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700165 result.appendFormat(" Jpeg thumbnail size: %d x %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700166 p.jpegThumbSize[0], p.jpegThumbSize[1]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700167 result.appendFormat(" Jpeg quality: %d, thumbnail quality: %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700168 p.jpegQuality, p.jpegThumbQuality);
169 result.appendFormat(" Jpeg rotation: %d\n", p.jpegRotation);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700170 result.appendFormat(" GPS tags %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700171 p.gpsEnabled ? "enabled" : "disabled");
172 if (p.gpsEnabled) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700173 result.appendFormat(" GPS lat x long x alt: %f x %f x %f\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700174 p.gpsCoordinates[0], p.gpsCoordinates[1],
175 p.gpsCoordinates[2]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700176 result.appendFormat(" GPS timestamp: %lld\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700177 p.gpsTimestamp);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700178 result.appendFormat(" GPS processing method: %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700179 p.gpsProcessingMethod.string());
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700180 }
181
182 result.append(" White balance mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700183 switch (p.wbMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700184 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_AUTO)
185 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_INCANDESCENT)
186 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_FLUORESCENT)
187 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_WARM_FLUORESCENT)
188 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_DAYLIGHT)
189 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT)
190 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_TWILIGHT)
191 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_SHADE)
192 default: result.append("UNKNOWN\n");
193 }
194
195 result.append(" Effect mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700196 switch (p.effectMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700197 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_OFF)
198 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_MONO)
199 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_NEGATIVE)
200 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_SOLARIZE)
201 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_SEPIA)
202 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_POSTERIZE)
203 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_WHITEBOARD)
204 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_BLACKBOARD)
205 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_AQUA)
206 default: result.append("UNKNOWN\n");
207 }
208
209 result.append(" Antibanding mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700210 switch (p.antibandingMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700211 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_AUTO)
212 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_OFF)
213 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_50HZ)
214 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_60HZ)
215 default: result.append("UNKNOWN\n");
216 }
217
218 result.append(" Scene mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700219 switch (p.sceneMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700220 case ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED:
221 result.append("AUTO\n"); break;
222 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_ACTION)
223 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_PORTRAIT)
224 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_LANDSCAPE)
225 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_NIGHT)
226 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT)
227 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_THEATRE)
228 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_BEACH)
229 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SNOW)
230 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SUNSET)
231 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO)
232 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_FIREWORKS)
233 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SPORTS)
234 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_PARTY)
235 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT)
236 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_BARCODE)
237 default: result.append("UNKNOWN\n");
238 }
239
240 result.append(" Flash mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700241 switch (p.flashMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700242 CASE_APPEND_ENUM(Parameters::FLASH_MODE_OFF)
243 CASE_APPEND_ENUM(Parameters::FLASH_MODE_AUTO)
244 CASE_APPEND_ENUM(Parameters::FLASH_MODE_ON)
245 CASE_APPEND_ENUM(Parameters::FLASH_MODE_TORCH)
246 CASE_APPEND_ENUM(Parameters::FLASH_MODE_RED_EYE)
247 CASE_APPEND_ENUM(Parameters::FLASH_MODE_INVALID)
248 default: result.append("UNKNOWN\n");
249 }
250
251 result.append(" Focus mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700252 switch (p.focusMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700253 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_AUTO)
254 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_MACRO)
255 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_CONTINUOUS_VIDEO)
256 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_CONTINUOUS_PICTURE)
257 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_EDOF)
258 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_INFINITY)
259 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_FIXED)
260 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_INVALID)
261 default: result.append("UNKNOWN\n");
262 }
263
264 result.append(" Focusing areas:\n");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700265 for (size_t i = 0; i < p.focusingAreas.size(); i++) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700266 result.appendFormat(" [ (%d, %d, %d, %d), weight %d ]\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700267 p.focusingAreas[i].left,
268 p.focusingAreas[i].top,
269 p.focusingAreas[i].right,
270 p.focusingAreas[i].bottom,
271 p.focusingAreas[i].weight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700272 }
273
274 result.appendFormat(" Exposure compensation index: %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700275 p.exposureCompensation);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700276
277 result.appendFormat(" AE lock %s, AWB lock %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700278 p.autoExposureLock ? "enabled" : "disabled",
279 p.autoWhiteBalanceLock ? "enabled" : "disabled" );
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700280
281 result.appendFormat(" Metering areas:\n");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700282 for (size_t i = 0; i < p.meteringAreas.size(); i++) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700283 result.appendFormat(" [ (%d, %d, %d, %d), weight %d ]\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700284 p.meteringAreas[i].left,
285 p.meteringAreas[i].top,
286 p.meteringAreas[i].right,
287 p.meteringAreas[i].bottom,
288 p.meteringAreas[i].weight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700289 }
290
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700291 result.appendFormat(" Zoom index: %d\n", p.zoom);
292 result.appendFormat(" Video size: %d x %d\n", p.videoWidth,
293 p.videoHeight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700294
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700295 result.appendFormat(" Recording hint is %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700296 p.recordingHint ? "set" : "not set");
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700297
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700298 result.appendFormat(" Video stabilization is %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700299 p.videoStabilization ? "enabled" : "disabled");
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700300
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700301 result.append(" Current streams:\n");
302 result.appendFormat(" Preview stream ID: %d\n", mPreviewStreamId);
Eino-Ville Talvalaea0d51b2012-08-28 01:25:43 -0700303 result.appendFormat(" Capture stream ID: %d\n",
304 mCaptureProcessor->getStreamId());
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700305 result.appendFormat(" Recording stream ID: %d\n", mRecordingStreamId);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700306
307 result.append(" Current requests:\n");
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700308 if (mPreviewRequest.entryCount() != 0) {
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700309 result.append(" Preview request:\n");
310 write(fd, result.string(), result.size());
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700311 mPreviewRequest.dump(fd, 2, 6);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700312 } else {
313 result.append(" Preview request: undefined\n");
314 write(fd, result.string(), result.size());
315 }
316
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700317 if (mCaptureRequest.entryCount() != 0) {
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700318 result = " Capture request:\n";
319 write(fd, result.string(), result.size());
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700320 mCaptureRequest.dump(fd, 2, 6);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700321 } else {
322 result = " Capture request: undefined\n";
323 write(fd, result.string(), result.size());
324 }
325
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700326 if (mRecordingRequest.entryCount() != 0) {
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700327 result = " Recording request:\n";
328 write(fd, result.string(), result.size());
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700329 mRecordingRequest.dump(fd, 2, 6);
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700330 } else {
331 result = " Recording request: undefined\n";
332 write(fd, result.string(), result.size());
333 }
334
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -0700335 mFrameProcessor->dump(fd, args);
336
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700337 result = " Device dump:\n";
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700338 write(fd, result.string(), result.size());
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700339
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700340 status_t res = mDevice->dump(fd, args);
341 if (res != OK) {
342 result = String8::format(" Error dumping device: %s (%d)",
343 strerror(-res), res);
344 write(fd, result.string(), result.size());
345 }
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700346
347#undef CASE_APPEND_ENUM
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700348 return NO_ERROR;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700349}
350
351// ICamera interface
352
353void Camera2Client::disconnect() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700354 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700355 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700356 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700357 status_t res;
358 if ( (res = checkPid(__FUNCTION__) ) != OK) return;
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700359
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700360 if (mDevice == 0) return;
361
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700362 stopPreviewL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700363
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700364 if (mPreviewStreamId != NO_STREAM) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700365 mDevice->deleteStream(mPreviewStreamId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700366 mPreviewStreamId = NO_STREAM;
367 }
368
Eino-Ville Talvalaea0d51b2012-08-28 01:25:43 -0700369 mCaptureProcessor->deleteStream();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700370
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -0700371 if (mRecordingStreamId != NO_STREAM) {
372 mDevice->deleteStream(mRecordingStreamId);
373 mRecordingStreamId = NO_STREAM;
374 }
375
Eino-Ville Talvalad86a6882012-08-28 11:34:14 -0700376 mCallbackProcessor->deleteStream();
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700377
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700378 mDevice.clear();
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700379 SharedParameters::Lock l(mParameters);
380 l.mParameters.state = Parameters::DISCONNECTED;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700381
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700382 CameraService::Client::disconnect();
383}
384
385status_t Camera2Client::connect(const sp<ICameraClient>& client) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700386 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700387 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700388 Mutex::Autolock icl(mICameraLock);
389
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700390 if (mClientPid != 0 && getCallingPid() != mClientPid) {
391 ALOGE("%s: Camera %d: Connection attempt from pid %d; "
392 "current locked to pid %d", __FUNCTION__,
393 mCameraId, getCallingPid(), mClientPid);
394 return BAD_VALUE;
395 }
396
397 mClientPid = getCallingPid();
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700398
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700399 mCameraClient = client;
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -0700400 mSharedCameraClient = client;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700401
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700402 SharedParameters::Lock l(mParameters);
403 l.mParameters.state = Parameters::STOPPED;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700404
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700405 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700406}
407
408status_t Camera2Client::lock() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700409 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700410 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700411 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700412 ALOGV("%s: Camera %d: Lock call from pid %d; current client pid %d",
413 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700414
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700415 if (mClientPid == 0) {
416 mClientPid = getCallingPid();
417 return OK;
418 }
419
420 if (mClientPid != getCallingPid()) {
421 ALOGE("%s: Camera %d: Lock call from pid %d; currently locked to pid %d",
422 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
423 return EBUSY;
424 }
425
426 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700427}
428
429status_t Camera2Client::unlock() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700430 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700431 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700432 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700433 ALOGV("%s: Camera %d: Unlock call from pid %d; current client pid %d",
434 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700435
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700436 // TODO: Check for uninterruptable conditions
437
438 if (mClientPid == getCallingPid()) {
439 mClientPid = 0;
440 mCameraClient.clear();
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -0700441 mSharedCameraClient.clear();
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700442 return OK;
443 }
444
445 ALOGE("%s: Camera %d: Unlock call from pid %d; currently locked to pid %d",
446 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
447 return EBUSY;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700448}
449
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700450status_t Camera2Client::setPreviewDisplay(
451 const sp<Surface>& surface) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700452 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700453 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700454 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700455 status_t res;
456 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700457
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700458 sp<IBinder> binder;
459 sp<ANativeWindow> window;
460 if (surface != 0) {
461 binder = surface->asBinder();
462 window = surface;
463 }
464
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700465 return setPreviewWindowL(binder,window);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700466}
467
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700468status_t Camera2Client::setPreviewTexture(
469 const sp<ISurfaceTexture>& surfaceTexture) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700470 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700471 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700472 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700473 status_t res;
474 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700475
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700476 sp<IBinder> binder;
477 sp<ANativeWindow> window;
478 if (surfaceTexture != 0) {
479 binder = surfaceTexture->asBinder();
480 window = new SurfaceTextureClient(surfaceTexture);
481 }
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700482 return setPreviewWindowL(binder, window);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700483}
484
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700485status_t Camera2Client::setPreviewWindowL(const sp<IBinder>& binder,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700486 sp<ANativeWindow> window) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700487 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700488 status_t res;
489
490 if (binder == mPreviewSurface) {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700491 ALOGV("%s: Camera %d: New window is same as old window",
492 __FUNCTION__, mCameraId);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700493 return NO_ERROR;
494 }
495
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700496 SharedParameters::Lock l(mParameters);
497 switch (l.mParameters.state) {
498 case Parameters::DISCONNECTED:
499 case Parameters::RECORD:
500 case Parameters::STILL_CAPTURE:
501 case Parameters::VIDEO_SNAPSHOT:
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700502 ALOGE("%s: Camera %d: Cannot set preview display while in state %s",
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700503 __FUNCTION__, mCameraId,
504 Parameters::getStateName(l.mParameters.state));
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700505 return INVALID_OPERATION;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700506 case Parameters::STOPPED:
507 case Parameters::WAITING_FOR_PREVIEW_WINDOW:
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700508 // OK
509 break;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700510 case Parameters::PREVIEW:
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700511 // Already running preview - need to stop and create a new stream
512 // TODO: Optimize this so that we don't wait for old stream to drain
513 // before spinning up new stream
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700514 mDevice->clearStreamingRequest();
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700515 l.mParameters.state = Parameters::WAITING_FOR_PREVIEW_WINDOW;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700516 break;
517 }
518
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700519 if (mPreviewStreamId != NO_STREAM) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700520 res = mDevice->waitUntilDrained();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700521 if (res != OK) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700522 ALOGE("%s: Error waiting for preview to drain: %s (%d)",
523 __FUNCTION__, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700524 return res;
525 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700526 res = mDevice->deleteStream(mPreviewStreamId);
527 if (res != OK) {
528 ALOGE("%s: Unable to delete old preview stream: %s (%d)",
529 __FUNCTION__, strerror(-res), res);
530 return res;
531 }
532 mPreviewStreamId = NO_STREAM;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700533 }
534
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700535 mPreviewSurface = binder;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700536 mPreviewWindow = window;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700537
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700538 if (l.mParameters.state == Parameters::WAITING_FOR_PREVIEW_WINDOW) {
539 return startPreviewL(l.mParameters, false);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700540 }
541
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700542 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700543}
544
545void Camera2Client::setPreviewCallbackFlag(int flag) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700546 ATRACE_CALL();
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700547 ALOGV("%s: Camera %d: Flag 0x%x", __FUNCTION__, mCameraId, flag);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700548 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700549 status_t res;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700550 if ( checkPid(__FUNCTION__) != OK) return;
551
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700552 SharedParameters::Lock l(mParameters);
553 setPreviewCallbackFlagL(l.mParameters, flag);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700554}
555
556void Camera2Client::setPreviewCallbackFlagL(Parameters &params, int flag) {
557 status_t res = OK;
558 if (flag & CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) {
559 ALOGV("%s: setting oneshot", __FUNCTION__);
560 params.previewCallbackOneShot = true;
561 }
562 if (params.previewCallbackFlags != (uint32_t)flag) {
563 params.previewCallbackFlags = flag;
564 switch(params.state) {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700565 case Parameters::PREVIEW:
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700566 res = startPreviewL(params, true);
567 break;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700568 case Parameters::RECORD:
569 case Parameters::VIDEO_SNAPSHOT:
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700570 res = startRecordingL(params, true);
571 break;
572 default:
573 break;
574 }
575 if (res != OK) {
576 ALOGE("%s: Camera %d: Unable to refresh request in state %s",
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700577 __FUNCTION__, mCameraId,
578 Parameters::getStateName(params.state));
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700579 }
580 }
581
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700582}
583
584status_t Camera2Client::startPreview() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700585 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700586 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700587 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700588 status_t res;
589 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700590 SharedParameters::Lock l(mParameters);
591 return startPreviewL(l.mParameters, false);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700592}
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700593
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700594status_t Camera2Client::startPreviewL(Parameters &params, bool restart) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700595 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700596 status_t res;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700597 if (params.state >= Parameters::PREVIEW && !restart) {
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700598 ALOGE("%s: Can't start preview in state %s",
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700599 __FUNCTION__,
600 Parameters::getStateName(params.state));
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700601 return INVALID_OPERATION;
602 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700603
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700604 if (mPreviewWindow == 0) {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700605 params.state = Parameters::WAITING_FOR_PREVIEW_WINDOW;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700606 return OK;
607 }
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700608 params.state = Parameters::STOPPED;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700609
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700610 res = updatePreviewStream(params);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700611 if (res != OK) {
612 ALOGE("%s: Camera %d: Unable to update preview stream: %s (%d)",
613 __FUNCTION__, mCameraId, strerror(-res), res);
614 return res;
615 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700616 bool callbacksEnabled = params.previewCallbackFlags &
617 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK;
618 if (callbacksEnabled) {
Eino-Ville Talvalad86a6882012-08-28 11:34:14 -0700619 res = mCallbackProcessor->updateStream(params);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700620 if (res != OK) {
621 ALOGE("%s: Camera %d: Unable to update callback stream: %s (%d)",
622 __FUNCTION__, mCameraId, strerror(-res), res);
623 return res;
624 }
625 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700626
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700627 if (mPreviewRequest.entryCount() == 0) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700628 res = updatePreviewRequest(params);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700629 if (res != OK) {
630 ALOGE("%s: Camera %d: Unable to create preview request: %s (%d)",
631 __FUNCTION__, mCameraId, strerror(-res), res);
632 return res;
633 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700634 }
635
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700636 if (callbacksEnabled) {
637 uint8_t outputStreams[2] =
Eino-Ville Talvalad86a6882012-08-28 11:34:14 -0700638 { mPreviewStreamId, mCallbackProcessor->getStreamId() };
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700639 res = mPreviewRequest.update(
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700640 ANDROID_REQUEST_OUTPUT_STREAMS,
641 outputStreams, 2);
642 } else {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700643 uint8_t outputStreams[1] = { mPreviewStreamId };
644 res = mPreviewRequest.update(
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700645 ANDROID_REQUEST_OUTPUT_STREAMS,
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700646 outputStreams, 1);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700647 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700648 if (res != OK) {
649 ALOGE("%s: Camera %d: Unable to set up preview request: %s (%d)",
650 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700651 return res;
652 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700653 res = mPreviewRequest.sort();
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700654 if (res != OK) {
655 ALOGE("%s: Camera %d: Error sorting preview request: %s (%d)",
656 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700657 return res;
658 }
659
660 res = mDevice->setStreamingRequest(mPreviewRequest);
661 if (res != OK) {
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700662 ALOGE("%s: Camera %d: Unable to set preview request to start preview: "
663 "%s (%d)",
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700664 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700665 return res;
666 }
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700667 params.state = Parameters::PREVIEW;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700668
669 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700670}
671
672void Camera2Client::stopPreview() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700673 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700674 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700675 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700676 status_t res;
677 if ( (res = checkPid(__FUNCTION__) ) != OK) return;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700678 stopPreviewL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700679}
680
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700681void Camera2Client::stopPreviewL() {
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700682 ATRACE_CALL();
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700683 Parameters::State state;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700684 {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700685 SharedParameters::Lock l(mParameters);
686 state = l.mParameters.state;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700687 }
688
689 switch (state) {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700690 case Parameters::DISCONNECTED:
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700691 ALOGE("%s: Camera %d: Call before initialized",
692 __FUNCTION__, mCameraId);
693 break;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700694 case Parameters::STOPPED:
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700695 break;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700696 case Parameters::STILL_CAPTURE:
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700697 ALOGE("%s: Camera %d: Cannot stop preview during still capture.",
698 __FUNCTION__, mCameraId);
699 break;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700700 case Parameters::RECORD:
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700701 // no break - identical to preview
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700702 case Parameters::PREVIEW:
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700703 mDevice->clearStreamingRequest();
Eino-Ville Talvala22671062012-07-20 18:30:37 -0700704 mDevice->waitUntilDrained();
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700705 // no break
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700706 case Parameters::WAITING_FOR_PREVIEW_WINDOW: {
707 SharedParameters::Lock l(mParameters);
708 l.mParameters.state = Parameters::STOPPED;
709 commandStopFaceDetectionL(l.mParameters);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700710 break;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700711 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700712 default:
713 ALOGE("%s: Camera %d: Unknown state %d", __FUNCTION__, mCameraId,
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700714 state);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700715 }
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700716}
717
718bool Camera2Client::previewEnabled() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700719 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700720 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700721 status_t res;
722 if ( (res = checkPid(__FUNCTION__) ) != OK) return false;
723
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700724 SharedParameters::Lock l(mParameters);
725 return l.mParameters.state == Parameters::PREVIEW;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700726}
727
728status_t Camera2Client::storeMetaDataInBuffers(bool enabled) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700729 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700730 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700731 status_t res;
732 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
733
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700734 SharedParameters::Lock l(mParameters);
735 switch (l.mParameters.state) {
736 case Parameters::RECORD:
737 case Parameters::VIDEO_SNAPSHOT:
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700738 ALOGE("%s: Camera %d: Can't be called in state %s",
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700739 __FUNCTION__, mCameraId,
740 Parameters::getStateName(l.mParameters.state));
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700741 return INVALID_OPERATION;
742 default:
743 // OK
744 break;
745 }
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700746
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700747 l.mParameters.storeMetadataInBuffers = enabled;
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700748
749 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700750}
751
752status_t Camera2Client::startRecording() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700753 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700754 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700755 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700756 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700757 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700758 SharedParameters::Lock l(mParameters);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700759
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700760 return startRecordingL(l.mParameters, false);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700761}
762
763status_t Camera2Client::startRecordingL(Parameters &params, bool restart) {
764 status_t res;
765 switch (params.state) {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700766 case Parameters::STOPPED:
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700767 res = startPreviewL(params, false);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700768 if (res != OK) return res;
769 break;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700770 case Parameters::PREVIEW:
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700771 // Ready to go
772 break;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700773 case Parameters::RECORD:
774 case Parameters::VIDEO_SNAPSHOT:
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700775 // OK to call this when recording is already on, just skip unless
776 // we're looking to restart
777 if (!restart) return OK;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700778 break;
779 default:
780 ALOGE("%s: Camera %d: Can't start recording in state %s",
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700781 __FUNCTION__, mCameraId,
782 Parameters::getStateName(params.state));
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700783 return INVALID_OPERATION;
784 };
785
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700786 if (!params.storeMetadataInBuffers) {
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700787 ALOGE("%s: Camera %d: Recording only supported in metadata mode, but "
788 "non-metadata recording mode requested!", __FUNCTION__,
789 mCameraId);
790 return INVALID_OPERATION;
791 }
792
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700793 res = updateRecordingStream(params);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700794 if (res != OK) {
795 ALOGE("%s: Camera %d: Unable to update recording stream: %s (%d)",
796 __FUNCTION__, mCameraId, strerror(-res), res);
797 return res;
798 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700799 bool callbacksEnabled = params.previewCallbackFlags &
800 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK;
801 if (callbacksEnabled) {
Eino-Ville Talvalad86a6882012-08-28 11:34:14 -0700802 res = mCallbackProcessor->updateStream(params);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700803 if (res != OK) {
804 ALOGE("%s: Camera %d: Unable to update callback stream: %s (%d)",
805 __FUNCTION__, mCameraId, strerror(-res), res);
806 return res;
807 }
808 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700809
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700810 if (mRecordingRequest.entryCount() == 0) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700811 res = updateRecordingRequest(params);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700812 if (res != OK) {
813 ALOGE("%s: Camera %d: Unable to create recording request: %s (%d)",
814 __FUNCTION__, mCameraId, strerror(-res), res);
815 return res;
816 }
817 }
818
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700819 if (callbacksEnabled) {
820 uint8_t outputStreams[3] =
Eino-Ville Talvalad86a6882012-08-28 11:34:14 -0700821 { mPreviewStreamId, mRecordingStreamId,
822 mCallbackProcessor->getStreamId() };
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700823 res = mRecordingRequest.update(
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700824 ANDROID_REQUEST_OUTPUT_STREAMS,
825 outputStreams, 3);
826 } else {
827 uint8_t outputStreams[2] = { mPreviewStreamId, mRecordingStreamId };
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700828 res = mRecordingRequest.update(
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700829 ANDROID_REQUEST_OUTPUT_STREAMS,
830 outputStreams, 2);
831 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700832 if (res != OK) {
833 ALOGE("%s: Camera %d: Unable to set up recording request: %s (%d)",
834 __FUNCTION__, mCameraId, strerror(-res), res);
835 return res;
836 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700837 res = mRecordingRequest.sort();
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700838 if (res != OK) {
839 ALOGE("%s: Camera %d: Error sorting recording request: %s (%d)",
840 __FUNCTION__, mCameraId, strerror(-res), res);
841 return res;
842 }
843
844 res = mDevice->setStreamingRequest(mRecordingRequest);
845 if (res != OK) {
846 ALOGE("%s: Camera %d: Unable to set recording request to start "
847 "recording: %s (%d)", __FUNCTION__, mCameraId,
848 strerror(-res), res);
849 return res;
850 }
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700851 if (params.state < Parameters::RECORD) {
852 params.state = Parameters::RECORD;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700853 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700854
855 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700856}
857
858void Camera2Client::stopRecording() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700859 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700860 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700861 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700862 SharedParameters::Lock l(mParameters);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700863
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700864 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700865 if ( (res = checkPid(__FUNCTION__) ) != OK) return;
866
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700867 switch (l.mParameters.state) {
868 case Parameters::RECORD:
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700869 // OK to stop
870 break;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700871 case Parameters::STOPPED:
872 case Parameters::PREVIEW:
873 case Parameters::STILL_CAPTURE:
874 case Parameters::VIDEO_SNAPSHOT:
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700875 default:
876 ALOGE("%s: Camera %d: Can't stop recording in state %s",
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700877 __FUNCTION__, mCameraId,
878 Parameters::getStateName(l.mParameters.state));
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700879 return;
880 };
881
882 // Back to preview. Since record can only be reached through preview,
883 // all preview stream setup should be up to date.
884 res = mDevice->setStreamingRequest(mPreviewRequest);
885 if (res != OK) {
886 ALOGE("%s: Camera %d: Unable to switch back to preview request: "
887 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
888 return;
889 }
890
891 // TODO: Should recording heap be freed? Can't do it yet since requests
892 // could still be in flight.
893
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700894 l.mParameters.state = Parameters::PREVIEW;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700895}
896
897bool Camera2Client::recordingEnabled() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700898 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700899 Mutex::Autolock icl(mICameraLock);
James Dong8da4cd72012-08-04 19:58:07 -0700900
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700901 if ( checkPid(__FUNCTION__) != OK) return false;
902
James Dong8da4cd72012-08-04 19:58:07 -0700903 return recordingEnabledL();
904}
905
906bool Camera2Client::recordingEnabledL() {
907 ATRACE_CALL();
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700908 SharedParameters::Lock l(mParameters);
James Dong8da4cd72012-08-04 19:58:07 -0700909
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700910 return (l.mParameters.state == Parameters::RECORD
911 || l.mParameters.state == Parameters::VIDEO_SNAPSHOT);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700912}
913
914void Camera2Client::releaseRecordingFrame(const sp<IMemory>& mem) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700915 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700916 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700917 status_t res;
918 if ( checkPid(__FUNCTION__) != OK) return;
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -0700919
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700920 SharedParameters::Lock l(mParameters);
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -0700921
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700922 // Make sure this is for the current heap
923 ssize_t offset;
924 size_t size;
925 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
926 if (heap->getHeapID() != mRecordingHeap->mHeap->getHeapID()) {
927 ALOGW("%s: Camera %d: Mismatched heap ID, ignoring release "
928 "(got %x, expected %x)", __FUNCTION__, mCameraId,
929 heap->getHeapID(), mRecordingHeap->mHeap->getHeapID());
930 return;
931 }
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700932 uint8_t *data = (uint8_t*)heap->getBase() + offset;
933 uint32_t type = *(uint32_t*)data;
934 if (type != kMetadataBufferTypeGrallocSource) {
935 ALOGE("%s: Camera %d: Recording frame type invalid (got %x, expected %x)",
936 __FUNCTION__, mCameraId, type, kMetadataBufferTypeGrallocSource);
937 return;
938 }
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -0700939
940 // Release the buffer back to the recording queue
941
942 buffer_handle_t imgHandle = *(buffer_handle_t*)(data + 4);
943
944 size_t itemIndex;
945 for (itemIndex = 0; itemIndex < mRecordingBuffers.size(); itemIndex++) {
946 const BufferItemConsumer::BufferItem item = mRecordingBuffers[itemIndex];
947 if (item.mBuf != BufferItemConsumer::INVALID_BUFFER_SLOT &&
948 item.mGraphicBuffer->handle == imgHandle) {
949 break;
950 }
951 }
952 if (itemIndex == mRecordingBuffers.size()) {
953 ALOGE("%s: Camera %d: Can't find buffer_handle_t %p in list of "
954 "outstanding buffers", __FUNCTION__, mCameraId, imgHandle);
955 return;
956 }
957
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700958 ALOGV("%s: Camera %d: Freeing buffer_handle_t %p", __FUNCTION__, mCameraId,
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -0700959 imgHandle);
960
961 res = mRecordingConsumer->releaseBuffer(mRecordingBuffers[itemIndex]);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700962 if (res != OK) {
963 ALOGE("%s: Camera %d: Unable to free recording frame (buffer_handle_t: %p):"
964 "%s (%d)",
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -0700965 __FUNCTION__, mCameraId, imgHandle, strerror(-res), res);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700966 return;
967 }
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -0700968 mRecordingBuffers.replaceAt(itemIndex);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700969
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700970 mRecordingHeapFree++;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700971}
972
973status_t Camera2Client::autoFocus() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700974 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700975 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700976 status_t res;
977 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
978
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700979 int triggerId;
980 {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700981 SharedParameters::Lock l(mParameters);
982 l.mParameters.currentAfTriggerId = ++l.mParameters.afTriggerCounter;
983 triggerId = l.mParameters.currentAfTriggerId;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700984 }
985
986 mDevice->triggerAutofocus(triggerId);
987
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700988 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700989}
990
991status_t Camera2Client::cancelAutoFocus() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700992 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700993 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700994 status_t res;
995 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
996
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700997 int triggerId;
998 {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700999 SharedParameters::Lock l(mParameters);
1000 triggerId = ++l.mParameters.afTriggerCounter;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001001 }
1002
1003 mDevice->triggerCancelAutofocus(triggerId);
1004
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001005 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001006}
1007
1008status_t Camera2Client::takePicture(int msgType) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001009 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001010 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001011 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001012 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001013
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001014 SharedParameters::Lock l(mParameters);
1015 switch (l.mParameters.state) {
1016 case Parameters::DISCONNECTED:
1017 case Parameters::STOPPED:
1018 case Parameters::WAITING_FOR_PREVIEW_WINDOW:
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001019 ALOGE("%s: Camera %d: Cannot take picture without preview enabled",
1020 __FUNCTION__, mCameraId);
1021 return INVALID_OPERATION;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001022 case Parameters::PREVIEW:
1023 case Parameters::RECORD:
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001024 // Good to go for takePicture
1025 break;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001026 case Parameters::STILL_CAPTURE:
1027 case Parameters::VIDEO_SNAPSHOT:
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001028 ALOGE("%s: Camera %d: Already taking a picture",
1029 __FUNCTION__, mCameraId);
1030 return INVALID_OPERATION;
1031 }
1032
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001033 ALOGV("%s: Camera %d: Starting picture capture", __FUNCTION__, mCameraId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001034
Eino-Ville Talvalaea0d51b2012-08-28 01:25:43 -07001035 res = mCaptureProcessor->updateStream(l.mParameters);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001036 if (res != OK) {
1037 ALOGE("%s: Camera %d: Can't set up still image stream: %s (%d)",
1038 __FUNCTION__, mCameraId, strerror(-res), res);
1039 return res;
1040 }
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001041
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001042 if (mCaptureRequest.entryCount() == 0) {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001043 res = updateCaptureRequest(l.mParameters);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -07001044 if (res != OK) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001045 ALOGE("%s: Camera %d: Can't create still image capture request: "
1046 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -07001047 return res;
1048 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001049 }
1050
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001051 bool callbacksEnabled = l.mParameters.previewCallbackFlags &
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001052 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001053 bool recordingEnabled = (l.mParameters.state == Parameters::RECORD);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001054
Eino-Ville Talvalaea0d51b2012-08-28 01:25:43 -07001055 int captureStreamId = mCaptureProcessor->getStreamId();
1056
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001057 int streamSwitch = (callbacksEnabled ? 0x2 : 0x0) +
1058 (recordingEnabled ? 0x1 : 0x0);
1059 switch ( streamSwitch ) {
1060 case 0: { // No recording, callbacks
Eino-Ville Talvalad86a6882012-08-28 11:34:14 -07001061 uint8_t streamIds[2] = {
1062 mPreviewStreamId,
1063 captureStreamId
1064 };
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001065 res = mCaptureRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS,
1066 streamIds, 2);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001067 break;
1068 }
1069 case 1: { // Recording
Eino-Ville Talvalad86a6882012-08-28 11:34:14 -07001070 uint8_t streamIds[3] = {
1071 mPreviewStreamId,
1072 mRecordingStreamId,
1073 captureStreamId
1074 };
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001075 res = mCaptureRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS,
1076 streamIds, 3);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001077 break;
1078 }
1079 case 2: { // Callbacks
Eino-Ville Talvalad86a6882012-08-28 11:34:14 -07001080 uint8_t streamIds[3] = {
1081 mPreviewStreamId,
1082 mCallbackProcessor->getStreamId(),
1083 captureStreamId
1084 };
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001085 res = mCaptureRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS,
1086 streamIds, 3);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001087 break;
1088 }
1089 case 3: { // Both
Eino-Ville Talvalad86a6882012-08-28 11:34:14 -07001090 uint8_t streamIds[4] = {
1091 mPreviewStreamId,
1092 mCallbackProcessor->getStreamId(),
1093 mRecordingStreamId,
1094 captureStreamId
1095 };
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001096 res = mCaptureRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS,
1097 streamIds, 4);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001098 break;
1099 }
1100 };
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001101 if (res != OK) {
1102 ALOGE("%s: Camera %d: Unable to set up still image capture request: "
1103 "%s (%d)",
1104 __FUNCTION__, mCameraId, strerror(-res), res);
1105 return res;
1106 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001107 res = mCaptureRequest.sort();
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001108 if (res != OK) {
1109 ALOGE("%s: Camera %d: Unable to sort capture request: %s (%d)",
1110 __FUNCTION__, mCameraId, strerror(-res), res);
1111 return res;
1112 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001113
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001114 CameraMetadata captureCopy = mCaptureRequest;
1115 if (captureCopy.entryCount() == 0) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001116 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device",
1117 __FUNCTION__, mCameraId);
1118 return NO_MEMORY;
1119 }
1120
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001121 if (l.mParameters.state == Parameters::PREVIEW) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001122 res = mDevice->clearStreamingRequest();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001123 if (res != OK) {
1124 ALOGE("%s: Camera %d: Unable to stop preview for still capture: "
1125 "%s (%d)",
1126 __FUNCTION__, mCameraId, strerror(-res), res);
1127 return res;
1128 }
1129 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001130 // TODO: Capture should be atomic with setStreamingRequest here
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001131 res = mDevice->capture(captureCopy);
1132 if (res != OK) {
1133 ALOGE("%s: Camera %d: Unable to submit still image capture request: "
1134 "%s (%d)",
1135 __FUNCTION__, mCameraId, strerror(-res), res);
1136 return res;
1137 }
1138
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001139 switch (l.mParameters.state) {
1140 case Parameters::PREVIEW:
1141 l.mParameters.state = Parameters::STILL_CAPTURE;
1142 res = commandStopFaceDetectionL(l.mParameters);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001143 if (res != OK) {
1144 ALOGE("%s: Camera %d: Unable to stop face detection for still capture",
1145 __FUNCTION__, mCameraId);
1146 return res;
1147 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001148 break;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001149 case Parameters::RECORD:
1150 l.mParameters.state = Parameters::VIDEO_SNAPSHOT;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001151 break;
1152 default:
1153 ALOGE("%s: Camera %d: Unknown state for still capture!",
1154 __FUNCTION__, mCameraId);
1155 return INVALID_OPERATION;
1156 }
1157
1158 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001159}
1160
1161status_t Camera2Client::setParameters(const String8& params) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001162 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -07001163 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001164 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001165 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001166 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
1167
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001168 SharedParameters::Lock l(mParameters);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001169
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001170 res = l.mParameters.set(params);
1171 if (res != OK) return res;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001172
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001173 res = updateRequests(l.mParameters);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001174
1175 return res;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001176}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001177
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001178String8 Camera2Client::getParameters() const {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001179 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001180 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001181 if ( checkPid(__FUNCTION__) != OK) return String8();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001182
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001183 SharedParameters::ReadLock l(mParameters);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001184
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001185 // TODO: Deal with focus distances
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001186 return l.mParameters.paramsFlattened;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001187}
1188
1189status_t Camera2Client::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001190 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001191 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001192 status_t res;
1193 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001194
1195 ALOGV("%s: Camera %d: Command %d (%d, %d)", __FUNCTION__, mCameraId,
1196 cmd, arg1, arg2);
1197
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001198 switch (cmd) {
1199 case CAMERA_CMD_START_SMOOTH_ZOOM:
1200 return commandStartSmoothZoomL();
1201 case CAMERA_CMD_STOP_SMOOTH_ZOOM:
1202 return commandStopSmoothZoomL();
1203 case CAMERA_CMD_SET_DISPLAY_ORIENTATION:
1204 return commandSetDisplayOrientationL(arg1);
1205 case CAMERA_CMD_ENABLE_SHUTTER_SOUND:
1206 return commandEnableShutterSoundL(arg1 == 1);
1207 case CAMERA_CMD_PLAY_RECORDING_SOUND:
1208 return commandPlayRecordingSoundL();
1209 case CAMERA_CMD_START_FACE_DETECTION:
1210 return commandStartFaceDetectionL(arg1);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001211 case CAMERA_CMD_STOP_FACE_DETECTION: {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001212 SharedParameters::Lock l(mParameters);
1213 return commandStopFaceDetectionL(l.mParameters);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001214 }
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001215 case CAMERA_CMD_ENABLE_FOCUS_MOVE_MSG:
1216 return commandEnableFocusMoveMsgL(arg1 == 1);
1217 case CAMERA_CMD_PING:
1218 return commandPingL();
1219 case CAMERA_CMD_SET_VIDEO_BUFFER_COUNT:
1220 return commandSetVideoBufferCountL(arg1);
1221 default:
1222 ALOGE("%s: Unknown command %d (arguments %d, %d)",
1223 __FUNCTION__, cmd, arg1, arg2);
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001224 return BAD_VALUE;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001225 }
1226}
James Dong983cf232012-08-01 16:39:55 -07001227
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001228status_t Camera2Client::commandStartSmoothZoomL() {
1229 ALOGE("%s: Unimplemented!", __FUNCTION__);
1230 return OK;
1231}
James Dong983cf232012-08-01 16:39:55 -07001232
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001233status_t Camera2Client::commandStopSmoothZoomL() {
1234 ALOGE("%s: Unimplemented!", __FUNCTION__);
1235 return OK;
1236}
James Dong983cf232012-08-01 16:39:55 -07001237
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001238status_t Camera2Client::commandSetDisplayOrientationL(int degrees) {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001239 int transform = Parameters::degToTransform(degrees,
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001240 mCameraFacing == CAMERA_FACING_FRONT);
1241 if (transform == -1) {
1242 ALOGE("%s: Camera %d: Error setting %d as display orientation value",
1243 __FUNCTION__, mCameraId, degrees);
1244 return BAD_VALUE;
1245 }
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001246 SharedParameters::Lock l(mParameters);
1247 if (transform != l.mParameters.previewTransform &&
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001248 mPreviewStreamId != NO_STREAM) {
1249 mDevice->setStreamTransform(mPreviewStreamId, transform);
1250 }
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001251 l.mParameters.previewTransform = transform;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001252 return OK;
1253}
1254
1255status_t Camera2Client::commandEnableShutterSoundL(bool enable) {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001256 SharedParameters::Lock l(mParameters);
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001257 if (enable) {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001258 l.mParameters.playShutterSound = true;
James Dong983cf232012-08-01 16:39:55 -07001259 return OK;
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001260 }
1261
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001262 // Disabling shutter sound may not be allowed. In that case only
1263 // allow the mediaserver process to disable the sound.
1264 char value[PROPERTY_VALUE_MAX];
1265 property_get("ro.camera.sound.forced", value, "0");
1266 if (strncmp(value, "0", 2) != 0) {
1267 // Disabling shutter sound is not allowed. Deny if the current
1268 // process is not mediaserver.
1269 if (getCallingPid() != getpid()) {
1270 ALOGE("Failed to disable shutter sound. Permission denied (pid %d)",
1271 getCallingPid());
1272 return PERMISSION_DENIED;
1273 }
1274 }
1275
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001276 l.mParameters.playShutterSound = false;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001277 return OK;
1278}
1279
1280status_t Camera2Client::commandPlayRecordingSoundL() {
1281 mCameraService->playSound(CameraService::SOUND_RECORDING);
1282 return OK;
1283}
1284
1285status_t Camera2Client::commandStartFaceDetectionL(int type) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001286 ALOGV("%s: Camera %d: Starting face detection",
1287 __FUNCTION__, mCameraId);
1288 status_t res;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001289 SharedParameters::Lock l(mParameters);
1290 switch (l.mParameters.state) {
1291 case Parameters::DISCONNECTED:
1292 case Parameters::STOPPED:
1293 case Parameters::WAITING_FOR_PREVIEW_WINDOW:
1294 case Parameters::STILL_CAPTURE:
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001295 ALOGE("%s: Camera %d: Cannot start face detection without preview active",
1296 __FUNCTION__, mCameraId);
1297 return INVALID_OPERATION;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001298 case Parameters::PREVIEW:
1299 case Parameters::RECORD:
1300 case Parameters::VIDEO_SNAPSHOT:
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001301 // Good to go for starting face detect
1302 break;
1303 }
1304 // Ignoring type
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001305 if (l.mParameters.fastInfo.bestFaceDetectMode ==
1306 ANDROID_STATS_FACE_DETECTION_OFF) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001307 ALOGE("%s: Camera %d: Face detection not supported",
1308 __FUNCTION__, mCameraId);
1309 return INVALID_OPERATION;
1310 }
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001311 if (l.mParameters.enableFaceDetect) return OK;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001312
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001313 l.mParameters.enableFaceDetect = true;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001314
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001315 res = updateRequests(l.mParameters);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001316
1317 return res;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001318}
1319
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001320status_t Camera2Client::commandStopFaceDetectionL(Parameters &params) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001321 status_t res = OK;
1322 ALOGV("%s: Camera %d: Stopping face detection",
1323 __FUNCTION__, mCameraId);
1324
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001325 if (!params.enableFaceDetect) return OK;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001326
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001327 params.enableFaceDetect = false;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001328
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001329 if (params.state == Parameters::PREVIEW
1330 || params.state == Parameters::RECORD
1331 || params.state == Parameters::VIDEO_SNAPSHOT) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001332 res = updateRequests(params);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001333 }
1334
1335 return res;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001336}
1337
1338status_t Camera2Client::commandEnableFocusMoveMsgL(bool enable) {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001339 SharedParameters::Lock l(mParameters);
1340 l.mParameters.enableFocusMoveMessages = enable;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001341
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001342 return OK;
1343}
1344
1345status_t Camera2Client::commandPingL() {
1346 // Always ping back if access is proper and device is alive
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001347 SharedParameters::Lock l(mParameters);
1348 if (l.mParameters.state != Parameters::DISCONNECTED) {
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001349 return OK;
1350 } else {
1351 return NO_INIT;
1352 }
1353}
1354
1355status_t Camera2Client::commandSetVideoBufferCountL(size_t count) {
James Dong8da4cd72012-08-04 19:58:07 -07001356 if (recordingEnabledL()) {
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001357 ALOGE("%s: Camera %d: Error setting video buffer count after "
1358 "recording was started", __FUNCTION__, mCameraId);
1359 return INVALID_OPERATION;
1360 }
1361
1362 // 32 is the current upper limit on the video buffer count for BufferQueue
1363 if (count > 32) {
1364 ALOGE("%s: Camera %d: Error setting %d as video buffer count value",
1365 __FUNCTION__, mCameraId, count);
1366 return BAD_VALUE;
1367 }
1368
1369 // Need to reallocate memory for heap
1370 if (mRecordingHeapCount != count) {
1371 if (mRecordingHeap != 0) {
1372 mRecordingHeap.clear();
1373 mRecordingHeap = NULL;
1374 }
1375 mRecordingHeapCount = count;
1376 }
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001377
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001378 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001379}
1380
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001381/** Device-related methods */
1382
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -07001383void Camera2Client::notifyError(int errorCode, int arg1, int arg2) {
1384 ALOGE("Error condition %d reported by HAL, arguments %d, %d", errorCode, arg1, arg2);
1385}
1386
1387void Camera2Client::notifyShutter(int frameNumber, nsecs_t timestamp) {
1388 ALOGV("%s: Shutter notification for frame %d at time %lld", __FUNCTION__,
1389 frameNumber, timestamp);
1390}
1391
1392void Camera2Client::notifyAutoFocus(uint8_t newState, int triggerId) {
1393 ALOGV("%s: Autofocus state now %d, last trigger %d",
1394 __FUNCTION__, newState, triggerId);
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001395 bool sendCompletedMessage = false;
1396 bool sendMovingMessage = false;
1397
1398 bool success = false;
1399 bool afInMotion = false;
1400 {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001401 SharedParameters::Lock l(mParameters);
1402 switch (l.mParameters.focusMode) {
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001403 case Parameters::FOCUS_MODE_AUTO:
1404 case Parameters::FOCUS_MODE_MACRO:
1405 // Don't send notifications upstream if they're not for the current AF
1406 // trigger. For example, if cancel was called in between, or if we
1407 // already sent a notification about this AF call.
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001408 if (triggerId != l.mParameters.currentAfTriggerId) break;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001409 switch (newState) {
1410 case ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED:
1411 success = true;
1412 // no break
1413 case ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
1414 sendCompletedMessage = true;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001415 l.mParameters.currentAfTriggerId = -1;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001416 break;
1417 case ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN:
1418 // Just starting focusing, ignore
1419 break;
1420 case ANDROID_CONTROL_AF_STATE_INACTIVE:
1421 case ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN:
1422 case ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED:
1423 default:
1424 // Unexpected in AUTO/MACRO mode
1425 ALOGE("%s: Unexpected AF state transition in AUTO/MACRO mode: %d",
1426 __FUNCTION__, newState);
1427 break;
1428 }
1429 break;
1430 case Parameters::FOCUS_MODE_CONTINUOUS_VIDEO:
1431 case Parameters::FOCUS_MODE_CONTINUOUS_PICTURE:
1432 switch (newState) {
1433 case ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED:
1434 success = true;
1435 // no break
1436 case ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
1437 // Don't send notifications upstream if they're not for
1438 // the current AF trigger. For example, if cancel was
1439 // called in between, or if we already sent a
1440 // notification about this AF call.
1441 // Send both a 'AF done' callback and a 'AF move' callback
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001442 if (triggerId != l.mParameters.currentAfTriggerId) break;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001443 sendCompletedMessage = true;
1444 afInMotion = false;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001445 if (l.mParameters.enableFocusMoveMessages &&
1446 l.mParameters.afInMotion) {
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001447 sendMovingMessage = true;
1448 }
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001449 l.mParameters.currentAfTriggerId = -1;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001450 break;
1451 case ANDROID_CONTROL_AF_STATE_INACTIVE:
1452 // Cancel was called, or we switched state; care if
1453 // currently moving
1454 afInMotion = false;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001455 if (l.mParameters.enableFocusMoveMessages &&
1456 l.mParameters.afInMotion) {
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001457 sendMovingMessage = true;
1458 }
1459 break;
1460 case ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN:
1461 // Start passive scan, inform upstream
1462 afInMotion = true;
1463 // no break
1464 case ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED:
1465 // Stop passive scan, inform upstream
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001466 if (l.mParameters.enableFocusMoveMessages) {
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001467 sendMovingMessage = true;
1468 }
1469 break;
1470 }
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001471 l.mParameters.afInMotion = afInMotion;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001472 break;
1473 case Parameters::FOCUS_MODE_EDOF:
1474 case Parameters::FOCUS_MODE_INFINITY:
1475 case Parameters::FOCUS_MODE_FIXED:
1476 default:
1477 if (newState != ANDROID_CONTROL_AF_STATE_INACTIVE) {
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -07001478 ALOGE("%s: Unexpected AF state change %d "
1479 "(ID %d) in focus mode %d",
1480 __FUNCTION__, newState, triggerId,
1481 l.mParameters.focusMode);
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001482 }
1483 }
1484 }
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001485 if (sendMovingMessage) {
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -07001486 SharedCameraClient::Lock l(mSharedCameraClient);
1487 if (l.mCameraClient != 0) {
1488 l.mCameraClient->notifyCallback(CAMERA_MSG_FOCUS_MOVE,
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001489 afInMotion ? 1 : 0, 0);
1490 }
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001491 }
Eino-Ville Talvala603b12e2012-08-08 09:25:58 -07001492 if (sendCompletedMessage) {
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -07001493 SharedCameraClient::Lock l(mSharedCameraClient);
1494 if (l.mCameraClient != 0) {
1495 l.mCameraClient->notifyCallback(CAMERA_MSG_FOCUS,
1496 success ? 1 : 0, 0);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001497 }
Eino-Ville Talvala603b12e2012-08-08 09:25:58 -07001498 }
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -07001499}
1500
1501void Camera2Client::notifyAutoExposure(uint8_t newState, int triggerId) {
1502 ALOGV("%s: Autoexposure state now %d, last trigger %d",
1503 __FUNCTION__, newState, triggerId);
1504}
1505
1506void Camera2Client::notifyAutoWhitebalance(uint8_t newState, int triggerId) {
1507 ALOGV("%s: Auto-whitebalance state now %d, last trigger %d",
1508 __FUNCTION__, newState, triggerId);
1509}
1510
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -07001511int Camera2Client::getCameraId() {
1512 return mCameraId;
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -07001513}
1514
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -07001515const sp<Camera2Device>& Camera2Client::getCameraDevice() {
1516 return mDevice;
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -07001517}
1518
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -07001519camera2::SharedParameters& Camera2Client::getParameters() {
1520 return mParameters;
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -07001521}
1522
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -07001523Camera2Client::SharedCameraClient::Lock::Lock(SharedCameraClient &client):
1524 mCameraClient(client.mCameraClient),
1525 mSharedClient(client) {
1526 mSharedClient.mCameraClientLock.lock();
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -07001527}
1528
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -07001529Camera2Client::SharedCameraClient::Lock::~Lock() {
1530 mSharedClient.mCameraClientLock.unlock();
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001531}
1532
Eino-Ville Talvalaea0d51b2012-08-28 01:25:43 -07001533Camera2Client::SharedCameraClient::SharedCameraClient(const sp<ICameraClient>&client):
1534 mCameraClient(client) {
1535}
1536
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -07001537Camera2Client::SharedCameraClient& Camera2Client::SharedCameraClient::operator=(
1538 const sp<ICameraClient>&client) {
1539 Mutex::Autolock l(mCameraClientLock);
1540 mCameraClient = client;
1541 return *this;
1542}
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001543
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -07001544void Camera2Client::SharedCameraClient::clear() {
1545 Mutex::Autolock l(mCameraClientLock);
1546 mCameraClient.clear();
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001547}
1548
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001549void Camera2Client::onRecordingFrameAvailable() {
1550 ATRACE_CALL();
1551 status_t res;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001552 sp<Camera2Heap> recordingHeap;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001553 size_t heapIdx = 0;
1554 nsecs_t timestamp;
1555 {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001556 SharedParameters::Lock l(mParameters);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001557
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07001558 BufferItemConsumer::BufferItem imgBuffer;
1559 res = mRecordingConsumer->acquireBuffer(&imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001560 if (res != OK) {
1561 ALOGE("%s: Camera %d: Error receiving recording buffer: %s (%d)",
1562 __FUNCTION__, mCameraId, strerror(-res), res);
1563 return;
1564 }
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07001565 timestamp = imgBuffer.mTimestamp;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001566
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001567 mRecordingFrameCount++;
1568 ALOGV("OnRecordingFrame: Frame %d", mRecordingFrameCount);
1569
1570 // TODO: Signal errors here upstream
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001571 if (l.mParameters.state != Parameters::RECORD &&
1572 l.mParameters.state != Parameters::VIDEO_SNAPSHOT) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001573 ALOGV("%s: Camera %d: Discarding recording image buffers received after "
1574 "recording done",
1575 __FUNCTION__, mCameraId);
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07001576 mRecordingConsumer->releaseBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001577 return;
1578 }
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001579
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001580 if (mRecordingHeap == 0) {
1581 const size_t bufferSize = 4 + sizeof(buffer_handle_t);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001582 ALOGV("%s: Camera %d: Creating recording heap with %d buffers of "
1583 "size %d bytes", __FUNCTION__, mCameraId,
James Dong983cf232012-08-01 16:39:55 -07001584 mRecordingHeapCount, bufferSize);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001585
James Dong983cf232012-08-01 16:39:55 -07001586 mRecordingHeap = new Camera2Heap(bufferSize, mRecordingHeapCount,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001587 "Camera2Client::RecordingHeap");
1588 if (mRecordingHeap->mHeap->getSize() == 0) {
1589 ALOGE("%s: Camera %d: Unable to allocate memory for recording",
1590 __FUNCTION__, mCameraId);
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07001591 mRecordingConsumer->releaseBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001592 return;
1593 }
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07001594 for (size_t i = 0; i < mRecordingBuffers.size(); i++) {
1595 if (mRecordingBuffers[i].mBuf !=
1596 BufferItemConsumer::INVALID_BUFFER_SLOT) {
1597 ALOGE("%s: Camera %d: Non-empty recording buffers list!",
1598 __FUNCTION__, mCameraId);
1599 }
1600 }
1601 mRecordingBuffers.clear();
1602 mRecordingBuffers.setCapacity(mRecordingHeapCount);
1603 mRecordingBuffers.insertAt(0, mRecordingHeapCount);
1604
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001605 mRecordingHeapHead = 0;
James Dong983cf232012-08-01 16:39:55 -07001606 mRecordingHeapFree = mRecordingHeapCount;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001607 }
1608
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001609 if ( mRecordingHeapFree == 0) {
1610 ALOGE("%s: Camera %d: No free recording buffers, dropping frame",
1611 __FUNCTION__, mCameraId);
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07001612 mRecordingConsumer->releaseBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001613 return;
1614 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001615
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001616 heapIdx = mRecordingHeapHead;
James Dong983cf232012-08-01 16:39:55 -07001617 mRecordingHeapHead = (mRecordingHeapHead + 1) % mRecordingHeapCount;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001618 mRecordingHeapFree--;
1619
1620 ALOGV("%s: Camera %d: Timestamp %lld",
1621 __FUNCTION__, mCameraId, timestamp);
1622
1623 ssize_t offset;
1624 size_t size;
1625 sp<IMemoryHeap> heap =
1626 mRecordingHeap->mBuffers[heapIdx]->getMemory(&offset,
1627 &size);
1628
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001629 uint8_t *data = (uint8_t*)heap->getBase() + offset;
1630 uint32_t type = kMetadataBufferTypeGrallocSource;
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07001631 *((uint32_t*)data) = type;
1632 *((buffer_handle_t*)(data + 4)) = imgBuffer.mGraphicBuffer->handle;
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001633 ALOGV("%s: Camera %d: Sending out buffer_handle_t %p",
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07001634 __FUNCTION__, mCameraId, imgBuffer.mGraphicBuffer->handle);
1635 mRecordingBuffers.replaceAt(imgBuffer, heapIdx);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001636 recordingHeap = mRecordingHeap;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001637 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001638
1639 // Call outside locked parameters to allow re-entrancy from notification
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -07001640 SharedCameraClient::Lock l(mSharedCameraClient);
1641 if (l.mCameraClient != 0) {
1642 l.mCameraClient->dataCallbackTimestamp(timestamp,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001643 CAMERA_MSG_VIDEO_FRAME,
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001644 recordingHeap->mBuffers[heapIdx]);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001645 }
1646}
1647
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001648/** Utility methods */
1649
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001650status_t Camera2Client::updateRequests(const Parameters &params) {
1651 status_t res;
1652
1653 res = updatePreviewRequest(params);
1654 if (res != OK) {
1655 ALOGE("%s: Camera %d: Unable to update preview request: %s (%d)",
1656 __FUNCTION__, mCameraId, strerror(-res), res);
1657 return res;
1658 }
1659 res = updateCaptureRequest(params);
1660 if (res != OK) {
1661 ALOGE("%s: Camera %d: Unable to update capture request: %s (%d)",
1662 __FUNCTION__, mCameraId, strerror(-res), res);
1663 return res;
1664 }
1665
1666 res = updateRecordingRequest(params);
1667 if (res != OK) {
1668 ALOGE("%s: Camera %d: Unable to update recording request: %s (%d)",
1669 __FUNCTION__, mCameraId, strerror(-res), res);
1670 return res;
1671 }
1672
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001673 if (params.state == Parameters::PREVIEW) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001674 res = mDevice->setStreamingRequest(mPreviewRequest);
1675 if (res != OK) {
1676 ALOGE("%s: Camera %d: Error streaming new preview request: %s (%d)",
1677 __FUNCTION__, mCameraId, strerror(-res), res);
1678 return res;
1679 }
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001680 } else if (params.state == Parameters::RECORD ||
1681 params.state == Parameters::VIDEO_SNAPSHOT) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001682 res = mDevice->setStreamingRequest(mRecordingRequest);
1683 if (res != OK) {
1684 ALOGE("%s: Camera %d: Error streaming new record request: %s (%d)",
1685 __FUNCTION__, mCameraId, strerror(-res), res);
1686 return res;
1687 }
1688 }
1689 return res;
1690}
1691
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001692status_t Camera2Client::updatePreviewStream(const Parameters &params) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001693 ATRACE_CALL();
1694 status_t res;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001695
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001696 if (mPreviewStreamId != NO_STREAM) {
1697 // Check if stream parameters have to change
1698 uint32_t currentWidth, currentHeight;
1699 res = mDevice->getStreamInfo(mPreviewStreamId,
1700 &currentWidth, &currentHeight, 0);
1701 if (res != OK) {
1702 ALOGE("%s: Camera %d: Error querying preview stream info: "
1703 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
1704 return res;
1705 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001706 if (currentWidth != (uint32_t)params.previewWidth ||
1707 currentHeight != (uint32_t)params.previewHeight) {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -07001708 ALOGV("%s: Camera %d: Preview size switch: %d x %d -> %d x %d",
1709 __FUNCTION__, mCameraId, currentWidth, currentHeight,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001710 params.previewWidth, params.previewHeight);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001711 res = mDevice->waitUntilDrained();
1712 if (res != OK) {
1713 ALOGE("%s: Camera %d: Error waiting for preview to drain: "
1714 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
1715 return res;
1716 }
1717 res = mDevice->deleteStream(mPreviewStreamId);
1718 if (res != OK) {
1719 ALOGE("%s: Camera %d: Unable to delete old output stream "
1720 "for preview: %s (%d)", __FUNCTION__, mCameraId,
1721 strerror(-res), res);
1722 return res;
1723 }
1724 mPreviewStreamId = NO_STREAM;
1725 }
1726 }
1727
1728 if (mPreviewStreamId == NO_STREAM) {
1729 res = mDevice->createStream(mPreviewWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001730 params.previewWidth, params.previewHeight,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001731 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0,
1732 &mPreviewStreamId);
1733 if (res != OK) {
1734 ALOGE("%s: Camera %d: Unable to create preview stream: %s (%d)",
1735 __FUNCTION__, mCameraId, strerror(-res), res);
1736 return res;
1737 }
1738 }
1739
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001740 res = mDevice->setStreamTransform(mPreviewStreamId,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001741 params.previewTransform);
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001742 if (res != OK) {
1743 ALOGE("%s: Camera %d: Unable to set preview stream transform: "
1744 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
1745 return res;
1746 }
1747
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001748 return OK;
1749}
1750
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001751status_t Camera2Client::updatePreviewRequest(const Parameters &params) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001752 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001753 status_t res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001754 if (mPreviewRequest.entryCount() == 0) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001755 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
1756 &mPreviewRequest);
1757 if (res != OK) {
1758 ALOGE("%s: Camera %d: Unable to create default preview request: "
1759 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
1760 return res;
1761 }
1762 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001763
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001764 res = updateRequestCommon(&mPreviewRequest, params);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001765 if (res != OK) {
1766 ALOGE("%s: Camera %d: Unable to update common entries of preview "
1767 "request: %s (%d)", __FUNCTION__, mCameraId,
1768 strerror(-res), res);
1769 return res;
1770 }
1771
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001772 return OK;
1773}
1774
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001775status_t Camera2Client::updateCaptureRequest(const Parameters &params) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001776 ATRACE_CALL();
1777 status_t res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001778 if (mCaptureRequest.entryCount() == 0) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001779 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_STILL_CAPTURE,
1780 &mCaptureRequest);
1781 if (res != OK) {
1782 ALOGE("%s: Camera %d: Unable to create default still image request:"
1783 " %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
1784 return res;
1785 }
1786 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001787
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001788 res = updateRequestCommon(&mCaptureRequest, params);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001789 if (res != OK) {
1790 ALOGE("%s: Camera %d: Unable to update common entries of capture "
1791 "request: %s (%d)", __FUNCTION__, mCameraId,
1792 strerror(-res), res);
1793 return res;
1794 }
1795
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001796 res = mCaptureRequest.update(ANDROID_JPEG_THUMBNAIL_SIZE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001797 params.jpegThumbSize, 2);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001798 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001799 res = mCaptureRequest.update(ANDROID_JPEG_THUMBNAIL_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001800 &params.jpegThumbQuality, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001801 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001802 res = mCaptureRequest.update(ANDROID_JPEG_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001803 &params.jpegQuality, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001804 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001805 res = mCaptureRequest.update(
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001806 ANDROID_JPEG_ORIENTATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001807 &params.jpegRotation, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001808 if (res != OK) return res;
1809
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001810 if (params.gpsEnabled) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001811 res = mCaptureRequest.update(
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001812 ANDROID_JPEG_GPS_COORDINATES,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001813 params.gpsCoordinates, 3);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001814 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001815 res = mCaptureRequest.update(
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001816 ANDROID_JPEG_GPS_TIMESTAMP,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001817 &params.gpsTimestamp, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001818 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001819 res = mCaptureRequest.update(
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001820 ANDROID_JPEG_GPS_PROCESSING_METHOD,
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001821 params.gpsProcessingMethod);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001822 if (res != OK) return res;
1823 } else {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001824 res = mCaptureRequest.erase(ANDROID_JPEG_GPS_COORDINATES);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001825 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001826 res = mCaptureRequest.erase(ANDROID_JPEG_GPS_TIMESTAMP);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001827 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001828 res = mCaptureRequest.erase(ANDROID_JPEG_GPS_PROCESSING_METHOD);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001829 if (res != OK) return res;
1830 }
1831
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001832 return OK;
1833}
1834
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001835status_t Camera2Client::updateRecordingRequest(const Parameters &params) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001836 ATRACE_CALL();
1837 status_t res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001838 if (mRecordingRequest.entryCount() == 0) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001839 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_VIDEO_RECORD,
1840 &mRecordingRequest);
1841 if (res != OK) {
1842 ALOGE("%s: Camera %d: Unable to create default recording request:"
1843 " %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
1844 return res;
1845 }
1846 }
1847
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001848 res = updateRequestCommon(&mRecordingRequest, params);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001849 if (res != OK) {
1850 ALOGE("%s: Camera %d: Unable to update common entries of recording "
1851 "request: %s (%d)", __FUNCTION__, mCameraId,
1852 strerror(-res), res);
1853 return res;
1854 }
1855
1856 return OK;
1857}
1858
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001859status_t Camera2Client::updateRecordingStream(const Parameters &params) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001860 status_t res;
1861
1862 if (mRecordingConsumer == 0) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001863 // Create CPU buffer queue endpoint. We need one more buffer here so that we can
1864 // always acquire and free a buffer when the heap is full; otherwise the consumer
1865 // will have buffers in flight we'll never clear out.
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07001866 mRecordingConsumer = new BufferItemConsumer(
1867 GRALLOC_USAGE_HW_VIDEO_ENCODER,
1868 mRecordingHeapCount + 1,
1869 true);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001870 mRecordingConsumer->setFrameAvailableListener(new RecordingWaiter(this));
1871 mRecordingConsumer->setName(String8("Camera2Client::RecordingConsumer"));
1872 mRecordingWindow = new SurfaceTextureClient(
1873 mRecordingConsumer->getProducerInterface());
1874 // Allocate memory later, since we don't know buffer size until receipt
1875 }
1876
1877 if (mRecordingStreamId != NO_STREAM) {
1878 // Check if stream parameters have to change
1879 uint32_t currentWidth, currentHeight;
1880 res = mDevice->getStreamInfo(mRecordingStreamId,
1881 &currentWidth, &currentHeight, 0);
1882 if (res != OK) {
1883 ALOGE("%s: Camera %d: Error querying recording output stream info: "
1884 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
1885 return res;
1886 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001887 if (currentWidth != (uint32_t)params.videoWidth ||
1888 currentHeight != (uint32_t)params.videoHeight) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001889 // TODO: Should wait to be sure previous recording has finished
1890 res = mDevice->deleteStream(mRecordingStreamId);
1891 if (res != OK) {
1892 ALOGE("%s: Camera %d: Unable to delete old output stream "
1893 "for recording: %s (%d)", __FUNCTION__, mCameraId,
1894 strerror(-res), res);
1895 return res;
1896 }
1897 mRecordingStreamId = NO_STREAM;
1898 }
1899 }
1900
1901 if (mRecordingStreamId == NO_STREAM) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001902 mRecordingFrameCount = 0;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001903 res = mDevice->createStream(mRecordingWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001904 params.videoWidth, params.videoHeight,
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001905 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0, &mRecordingStreamId);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001906 if (res != OK) {
1907 ALOGE("%s: Camera %d: Can't create output stream for recording: "
1908 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
1909 return res;
1910 }
1911 }
1912
1913 return OK;
1914}
1915
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001916status_t Camera2Client::updateRequestCommon(CameraMetadata *request,
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001917 const Parameters &params) const {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001918 ATRACE_CALL();
1919 status_t res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001920 res = request->update(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
1921 params.previewFpsRange, 2);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001922 if (res != OK) return res;
1923
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001924 uint8_t wbMode = params.autoWhiteBalanceLock ?
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001925 (uint8_t)ANDROID_CONTROL_AWB_LOCKED : params.wbMode;
1926 res = request->update(ANDROID_CONTROL_AWB_MODE,
1927 &wbMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001928 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001929 res = request->update(ANDROID_CONTROL_EFFECT_MODE,
1930 &params.effectMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001931 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001932 res = request->update(ANDROID_CONTROL_AE_ANTIBANDING_MODE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001933 &params.antibandingMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001934 if (res != OK) return res;
1935
1936 uint8_t controlMode =
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001937 (params.sceneMode == ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED) ?
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001938 ANDROID_CONTROL_AUTO : ANDROID_CONTROL_USE_SCENE_MODE;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001939 res = request->update(ANDROID_CONTROL_MODE,
1940 &controlMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001941 if (res != OK) return res;
1942 if (controlMode == ANDROID_CONTROL_USE_SCENE_MODE) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001943 res = request->update(ANDROID_CONTROL_SCENE_MODE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001944 &params.sceneMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001945 if (res != OK) return res;
1946 }
1947
1948 uint8_t flashMode = ANDROID_FLASH_OFF;
1949 uint8_t aeMode;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001950 switch (params.flashMode) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001951 case Parameters::FLASH_MODE_OFF:
1952 aeMode = ANDROID_CONTROL_AE_ON; break;
1953 case Parameters::FLASH_MODE_AUTO:
1954 aeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH; break;
1955 case Parameters::FLASH_MODE_ON:
1956 aeMode = ANDROID_CONTROL_AE_ON_ALWAYS_FLASH; break;
1957 case Parameters::FLASH_MODE_TORCH:
1958 aeMode = ANDROID_CONTROL_AE_ON;
1959 flashMode = ANDROID_FLASH_TORCH;
1960 break;
1961 case Parameters::FLASH_MODE_RED_EYE:
1962 aeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE; break;
1963 default:
1964 ALOGE("%s: Camera %d: Unknown flash mode %d", __FUNCTION__,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001965 mCameraId, params.flashMode);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001966 return BAD_VALUE;
1967 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001968 if (params.autoExposureLock) aeMode = ANDROID_CONTROL_AE_LOCKED;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001969
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001970 res = request->update(ANDROID_FLASH_MODE,
1971 &flashMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001972 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001973 res = request->update(ANDROID_CONTROL_AE_MODE,
1974 &aeMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001975 if (res != OK) return res;
1976
1977 float focusDistance = 0; // infinity focus in diopters
1978 uint8_t focusMode;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001979 switch (params.focusMode) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001980 case Parameters::FOCUS_MODE_AUTO:
1981 case Parameters::FOCUS_MODE_MACRO:
1982 case Parameters::FOCUS_MODE_CONTINUOUS_VIDEO:
1983 case Parameters::FOCUS_MODE_CONTINUOUS_PICTURE:
1984 case Parameters::FOCUS_MODE_EDOF:
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001985 focusMode = params.focusMode;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001986 break;
1987 case Parameters::FOCUS_MODE_INFINITY:
1988 case Parameters::FOCUS_MODE_FIXED:
1989 focusMode = ANDROID_CONTROL_AF_OFF;
1990 break;
1991 default:
1992 ALOGE("%s: Camera %d: Unknown focus mode %d", __FUNCTION__,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001993 mCameraId, params.focusMode);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001994 return BAD_VALUE;
1995 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001996 res = request->update(ANDROID_LENS_FOCUS_DISTANCE,
1997 &focusDistance, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001998 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001999 res = request->update(ANDROID_CONTROL_AF_MODE,
2000 &focusMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002001 if (res != OK) return res;
2002
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002003 size_t focusingAreasSize = params.focusingAreas.size() * 5;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002004 int32_t *focusingAreas = new int32_t[focusingAreasSize];
2005 for (size_t i = 0; i < focusingAreasSize; i += 5) {
Eino-Ville Talvalaf17b6cf2012-08-25 17:12:18 -07002006 if (params.focusingAreas[i].weight != 0) {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07002007 focusingAreas[i + 0] =
2008 params.normalizedXToArray(params.focusingAreas[i].left);
2009 focusingAreas[i + 1] =
2010 params.normalizedYToArray(params.focusingAreas[i].top);
2011 focusingAreas[i + 2] =
2012 params.normalizedXToArray(params.focusingAreas[i].right);
2013 focusingAreas[i + 3] =
2014 params.normalizedYToArray(params.focusingAreas[i].bottom);
Eino-Ville Talvalaf17b6cf2012-08-25 17:12:18 -07002015 } else {
2016 focusingAreas[i + 0] = 0;
2017 focusingAreas[i + 1] = 0;
2018 focusingAreas[i + 2] = 0;
2019 focusingAreas[i + 3] = 0;
2020 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002021 focusingAreas[i + 4] = params.focusingAreas[i].weight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002022 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002023 res = request->update(ANDROID_CONTROL_AF_REGIONS,
2024 focusingAreas,focusingAreasSize);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002025 if (res != OK) return res;
2026 delete[] focusingAreas;
2027
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002028 res = request->update(ANDROID_CONTROL_AE_EXP_COMPENSATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002029 &params.exposureCompensation, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002030 if (res != OK) return res;
2031
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002032 size_t meteringAreasSize = params.meteringAreas.size() * 5;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002033 int32_t *meteringAreas = new int32_t[meteringAreasSize];
2034 for (size_t i = 0; i < meteringAreasSize; i += 5) {
Eino-Ville Talvalaf17b6cf2012-08-25 17:12:18 -07002035 if (params.meteringAreas[i].weight != 0) {
2036 meteringAreas[i + 0] =
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07002037 params.normalizedXToArray(params.meteringAreas[i].left);
Eino-Ville Talvalaf17b6cf2012-08-25 17:12:18 -07002038 meteringAreas[i + 1] =
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07002039 params.normalizedYToArray(params.meteringAreas[i].top);
Eino-Ville Talvalaf17b6cf2012-08-25 17:12:18 -07002040 meteringAreas[i + 2] =
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07002041 params.normalizedXToArray(params.meteringAreas[i].right);
Eino-Ville Talvalaf17b6cf2012-08-25 17:12:18 -07002042 meteringAreas[i + 3] =
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07002043 params.normalizedYToArray(params.meteringAreas[i].bottom);
Eino-Ville Talvalaf17b6cf2012-08-25 17:12:18 -07002044 } else {
2045 meteringAreas[i + 0] = 0;
2046 meteringAreas[i + 1] = 0;
2047 meteringAreas[i + 2] = 0;
2048 meteringAreas[i + 3] = 0;
2049 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002050 meteringAreas[i + 4] = params.meteringAreas[i].weight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002051 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002052 res = request->update(ANDROID_CONTROL_AE_REGIONS,
2053 meteringAreas, meteringAreasSize);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002054 if (res != OK) return res;
2055
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002056 res = request->update(ANDROID_CONTROL_AWB_REGIONS,
2057 meteringAreas, meteringAreasSize);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002058 if (res != OK) return res;
2059 delete[] meteringAreas;
2060
2061 // Need to convert zoom index into a crop rectangle. The rectangle is
2062 // chosen to maximize its area on the sensor
2063
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002064 camera_metadata_ro_entry_t maxDigitalZoom =
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07002065 mParameters.staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002066 float zoomIncrement = (maxDigitalZoom.data.f[0] - 1) /
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07002067 (params.NUM_ZOOM_STEPS-1);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002068 float zoomRatio = 1 + zoomIncrement * params.zoom;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002069
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002070 float zoomLeft, zoomTop, zoomWidth, zoomHeight;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002071 if (params.previewWidth >= params.previewHeight) {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07002072 zoomWidth = params.fastInfo.arrayWidth / zoomRatio;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002073 zoomHeight = zoomWidth *
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002074 params.previewHeight / params.previewWidth;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002075 } else {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07002076 zoomHeight = params.fastInfo.arrayHeight / zoomRatio;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002077 zoomWidth = zoomHeight *
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002078 params.previewWidth / params.previewHeight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002079 }
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07002080 zoomLeft = (params.fastInfo.arrayWidth - zoomWidth) / 2;
2081 zoomTop = (params.fastInfo.arrayHeight - zoomHeight) / 2;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002082
2083 int32_t cropRegion[3] = { zoomLeft, zoomTop, zoomWidth };
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002084 res = request->update(ANDROID_SCALER_CROP_REGION,
2085 cropRegion, 3);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002086 if (res != OK) return res;
2087
2088 // TODO: Decide how to map recordingHint, or whether just to ignore it
2089
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002090 uint8_t vstabMode = params.videoStabilization ?
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002091 ANDROID_CONTROL_VIDEO_STABILIZATION_ON :
2092 ANDROID_CONTROL_VIDEO_STABILIZATION_OFF;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002093 res = request->update(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002094 &vstabMode, 1);
2095 if (res != OK) return res;
2096
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002097 uint8_t faceDetectMode = params.enableFaceDetect ?
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07002098 params.fastInfo.bestFaceDetectMode :
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002099 (uint8_t)ANDROID_STATS_FACE_DETECTION_OFF;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002100 res = request->update(ANDROID_STATS_FACE_DETECT_MODE,
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002101 &faceDetectMode, 1);
2102 if (res != OK) return res;
2103
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002104 return OK;
2105}
2106
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002107size_t Camera2Client::calculateBufferSize(int width, int height,
2108 int format, int stride) {
2109 switch (format) {
2110 case HAL_PIXEL_FORMAT_YCbCr_422_SP: // NV16
2111 return width * height * 2;
2112 case HAL_PIXEL_FORMAT_YCrCb_420_SP: // NV21
2113 return width * height * 3 / 2;
2114 case HAL_PIXEL_FORMAT_YCbCr_422_I: // YUY2
2115 return width * height * 2;
2116 case HAL_PIXEL_FORMAT_YV12: { // YV12
2117 size_t ySize = stride * height;
Eino-Ville Talvalaf17b6cf2012-08-25 17:12:18 -07002118 size_t uvStride = (stride / 2 + 0xF) & ~0xF;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002119 size_t uvSize = uvStride * height / 2;
2120 return ySize + uvSize * 2;
2121 }
2122 case HAL_PIXEL_FORMAT_RGB_565:
2123 return width * height * 2;
2124 case HAL_PIXEL_FORMAT_RGBA_8888:
2125 return width * height * 4;
2126 case HAL_PIXEL_FORMAT_RAW_SENSOR:
2127 return width * height * 2;
2128 default:
2129 ALOGE("%s: Unknown preview format: %x",
2130 __FUNCTION__, format);
2131 return 0;
2132 }
2133}
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002134
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07002135} // namespace android