blob: d29644564b332db097b19612444617bd73c73432 [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 Talvala177bd342012-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 Talvala228a5382012-08-13 12:16:06 -070058 mCallbackStreamId(NO_STREAM),
59 mCallbackHeapId(0),
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -070060 mRecordingStreamId(NO_STREAM),
James Dong983cf232012-08-01 16:39:55 -070061 mRecordingHeapCount(kDefaultRecordingHeapCount)
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070062{
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070063 ATRACE_CALL();
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -070064 ALOGV("%s: Created client for camera %d", __FUNCTION__, cameraId);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070065
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070066 mDevice = new Camera2Device(cameraId);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -070067
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -070068 SharedParameters::Lock l(mParameters);
69 l.mParameters.state = Parameters::DISCONNECTED;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070070}
71
Eino-Ville Talvala3a609142012-07-31 14:36:26 -070072status_t Camera2Client::checkPid(const char* checkLocation) const {
73 int callingPid = getCallingPid();
74 if (callingPid == mClientPid) return NO_ERROR;
75
76 ALOGE("%s: attempt to use a locked camera from a different process"
77 " (old pid %d, new pid %d)", checkLocation, mClientPid, callingPid);
78 return PERMISSION_DENIED;
79}
80
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070081status_t Camera2Client::initialize(camera_module_t *module)
82{
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070083 ATRACE_CALL();
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -070084 ALOGV("%s: Initializing client for camera %d", __FUNCTION__, mCameraId);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070085 status_t res;
86
87 res = mDevice->initialize(module);
88 if (res != OK) {
89 ALOGE("%s: Camera %d: unable to initialize device: %s (%d)",
90 __FUNCTION__, mCameraId, strerror(-res), res);
91 return NO_INIT;
92 }
93
Eino-Ville Talvala174181e2012-08-03 13:53:39 -070094 res = mDevice->setNotifyCallback(this);
95
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -070096 SharedParameters::Lock l(mParameters);
97
98 res = l.mParameters.initialize(&(mDevice->info()));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070099 if (res != OK) {
100 ALOGE("%s: Camera %d: unable to build defaults: %s (%d)",
101 __FUNCTION__, mCameraId, strerror(-res), res);
102 return NO_INIT;
103 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -0700104
Eino-Ville Talvala177bd342012-08-28 01:25:43 -0700105 mFrameProcessor = new FrameProcessor(this);
106 String8 frameThreadName = String8::format("Camera2Client[%d]::FrameProcessor",
107 mCameraId);
108 mFrameProcessor->run(frameThreadName.string());
109
110 mCaptureProcessor = new CaptureProcessor(this);
111 String8 captureThreadName =
112 String8::format("Camera2Client[%d]::CaptureProcessor", mCameraId);
113 mCaptureProcessor->run(captureThreadName.string());
114
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700115 if (gLogLevel >= 1) {
116 ALOGD("%s: Default parameters converted from camera %d:", __FUNCTION__,
117 mCameraId);
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700118 ALOGD("%s", l.mParameters.paramsFlattened.string());
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700119 }
120
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700121 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700122}
123
124Camera2Client::~Camera2Client() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700125 ATRACE_CALL();
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -0700126 ALOGV("%s: Camera %d: Shutting down client.", __FUNCTION__, mCameraId);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700127
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700128 mDestructionStarted = true;
129
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700130 // Rewrite mClientPid to allow shutdown by CameraService
131 mClientPid = getCallingPid();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700132 disconnect();
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -0700133
134 mFrameProcessor->requestExit();
135 ALOGV("%s: Camera %d: Shutdown complete", __FUNCTION__, mCameraId);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700136}
137
138status_t Camera2Client::dump(int fd, const Vector<String16>& args) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700139 String8 result;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700140 result.appendFormat("Client2[%d] (%p) PID: %d, dump:\n",
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700141 mCameraId,
142 getCameraClient()->asBinder().get(),
143 mClientPid);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700144 result.append(" State: ");
145#define CASE_APPEND_ENUM(x) case x: result.append(#x "\n"); break;
146
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700147 const Parameters& p = mParameters.unsafeAccess();
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700148
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700149 result.append(Parameters::getStateName(p.state));
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700150
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700151 result.append("\n Current parameters:\n");
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700152 result.appendFormat(" Preview size: %d x %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700153 p.previewWidth, p.previewHeight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700154 result.appendFormat(" Preview FPS range: %d - %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700155 p.previewFpsRange[0], p.previewFpsRange[1]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700156 result.appendFormat(" Preview HAL pixel format: 0x%x\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700157 p.previewFormat);
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700158 result.appendFormat(" Preview transform: %x\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700159 p.previewTransform);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700160 result.appendFormat(" Picture size: %d x %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700161 p.pictureWidth, p.pictureHeight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700162 result.appendFormat(" Jpeg thumbnail size: %d x %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700163 p.jpegThumbSize[0], p.jpegThumbSize[1]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700164 result.appendFormat(" Jpeg quality: %d, thumbnail quality: %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700165 p.jpegQuality, p.jpegThumbQuality);
166 result.appendFormat(" Jpeg rotation: %d\n", p.jpegRotation);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700167 result.appendFormat(" GPS tags %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700168 p.gpsEnabled ? "enabled" : "disabled");
169 if (p.gpsEnabled) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700170 result.appendFormat(" GPS lat x long x alt: %f x %f x %f\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700171 p.gpsCoordinates[0], p.gpsCoordinates[1],
172 p.gpsCoordinates[2]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700173 result.appendFormat(" GPS timestamp: %lld\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700174 p.gpsTimestamp);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700175 result.appendFormat(" GPS processing method: %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700176 p.gpsProcessingMethod.string());
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700177 }
178
179 result.append(" White balance mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700180 switch (p.wbMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700181 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_AUTO)
182 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_INCANDESCENT)
183 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_FLUORESCENT)
184 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_WARM_FLUORESCENT)
185 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_DAYLIGHT)
186 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT)
187 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_TWILIGHT)
188 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_SHADE)
189 default: result.append("UNKNOWN\n");
190 }
191
192 result.append(" Effect mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700193 switch (p.effectMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700194 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_OFF)
195 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_MONO)
196 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_NEGATIVE)
197 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_SOLARIZE)
198 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_SEPIA)
199 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_POSTERIZE)
200 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_WHITEBOARD)
201 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_BLACKBOARD)
202 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_AQUA)
203 default: result.append("UNKNOWN\n");
204 }
205
206 result.append(" Antibanding mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700207 switch (p.antibandingMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700208 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_AUTO)
209 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_OFF)
210 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_50HZ)
211 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_60HZ)
212 default: result.append("UNKNOWN\n");
213 }
214
215 result.append(" Scene mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700216 switch (p.sceneMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700217 case ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED:
218 result.append("AUTO\n"); break;
219 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_ACTION)
220 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_PORTRAIT)
221 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_LANDSCAPE)
222 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_NIGHT)
223 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT)
224 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_THEATRE)
225 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_BEACH)
226 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SNOW)
227 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SUNSET)
228 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO)
229 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_FIREWORKS)
230 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SPORTS)
231 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_PARTY)
232 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT)
233 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_BARCODE)
234 default: result.append("UNKNOWN\n");
235 }
236
237 result.append(" Flash mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700238 switch (p.flashMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700239 CASE_APPEND_ENUM(Parameters::FLASH_MODE_OFF)
240 CASE_APPEND_ENUM(Parameters::FLASH_MODE_AUTO)
241 CASE_APPEND_ENUM(Parameters::FLASH_MODE_ON)
242 CASE_APPEND_ENUM(Parameters::FLASH_MODE_TORCH)
243 CASE_APPEND_ENUM(Parameters::FLASH_MODE_RED_EYE)
244 CASE_APPEND_ENUM(Parameters::FLASH_MODE_INVALID)
245 default: result.append("UNKNOWN\n");
246 }
247
248 result.append(" Focus mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700249 switch (p.focusMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700250 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_AUTO)
251 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_MACRO)
252 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_CONTINUOUS_VIDEO)
253 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_CONTINUOUS_PICTURE)
254 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_EDOF)
255 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_INFINITY)
256 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_FIXED)
257 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_INVALID)
258 default: result.append("UNKNOWN\n");
259 }
260
261 result.append(" Focusing areas:\n");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700262 for (size_t i = 0; i < p.focusingAreas.size(); i++) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700263 result.appendFormat(" [ (%d, %d, %d, %d), weight %d ]\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700264 p.focusingAreas[i].left,
265 p.focusingAreas[i].top,
266 p.focusingAreas[i].right,
267 p.focusingAreas[i].bottom,
268 p.focusingAreas[i].weight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700269 }
270
271 result.appendFormat(" Exposure compensation index: %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700272 p.exposureCompensation);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700273
274 result.appendFormat(" AE lock %s, AWB lock %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700275 p.autoExposureLock ? "enabled" : "disabled",
276 p.autoWhiteBalanceLock ? "enabled" : "disabled" );
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700277
278 result.appendFormat(" Metering areas:\n");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700279 for (size_t i = 0; i < p.meteringAreas.size(); i++) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700280 result.appendFormat(" [ (%d, %d, %d, %d), weight %d ]\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700281 p.meteringAreas[i].left,
282 p.meteringAreas[i].top,
283 p.meteringAreas[i].right,
284 p.meteringAreas[i].bottom,
285 p.meteringAreas[i].weight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700286 }
287
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700288 result.appendFormat(" Zoom index: %d\n", p.zoom);
289 result.appendFormat(" Video size: %d x %d\n", p.videoWidth,
290 p.videoHeight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700291
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700292 result.appendFormat(" Recording hint is %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700293 p.recordingHint ? "set" : "not set");
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700294
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700295 result.appendFormat(" Video stabilization is %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700296 p.videoStabilization ? "enabled" : "disabled");
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700297
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700298 result.append(" Current streams:\n");
299 result.appendFormat(" Preview stream ID: %d\n", mPreviewStreamId);
Eino-Ville Talvala177bd342012-08-28 01:25:43 -0700300 result.appendFormat(" Capture stream ID: %d\n",
301 mCaptureProcessor->getStreamId());
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700302 result.appendFormat(" Recording stream ID: %d\n", mRecordingStreamId);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700303
304 result.append(" Current requests:\n");
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700305 if (mPreviewRequest.entryCount() != 0) {
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700306 result.append(" Preview request:\n");
307 write(fd, result.string(), result.size());
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700308 mPreviewRequest.dump(fd, 2, 6);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700309 } else {
310 result.append(" Preview request: undefined\n");
311 write(fd, result.string(), result.size());
312 }
313
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700314 if (mCaptureRequest.entryCount() != 0) {
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700315 result = " Capture request:\n";
316 write(fd, result.string(), result.size());
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700317 mCaptureRequest.dump(fd, 2, 6);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700318 } else {
319 result = " Capture request: undefined\n";
320 write(fd, result.string(), result.size());
321 }
322
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700323 if (mRecordingRequest.entryCount() != 0) {
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700324 result = " Recording request:\n";
325 write(fd, result.string(), result.size());
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700326 mRecordingRequest.dump(fd, 2, 6);
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700327 } else {
328 result = " Recording request: undefined\n";
329 write(fd, result.string(), result.size());
330 }
331
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -0700332 mFrameProcessor->dump(fd, args);
333
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700334 result = " Device dump:\n";
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700335 write(fd, result.string(), result.size());
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700336
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700337 status_t res = mDevice->dump(fd, args);
338 if (res != OK) {
339 result = String8::format(" Error dumping device: %s (%d)",
340 strerror(-res), res);
341 write(fd, result.string(), result.size());
342 }
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700343
344#undef CASE_APPEND_ENUM
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700345 return NO_ERROR;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700346}
347
348// ICamera interface
349
350void Camera2Client::disconnect() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700351 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700352 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700353 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700354 status_t res;
355 if ( (res = checkPid(__FUNCTION__) ) != OK) return;
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700356
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700357 if (mDevice == 0) return;
358
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700359 stopPreviewL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700360
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700361 if (mPreviewStreamId != NO_STREAM) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700362 mDevice->deleteStream(mPreviewStreamId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700363 mPreviewStreamId = NO_STREAM;
364 }
365
Eino-Ville Talvala177bd342012-08-28 01:25:43 -0700366 mCaptureProcessor->deleteStream();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700367
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -0700368 if (mRecordingStreamId != NO_STREAM) {
369 mDevice->deleteStream(mRecordingStreamId);
370 mRecordingStreamId = NO_STREAM;
371 }
372
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700373 if (mCallbackStreamId != NO_STREAM) {
374 mDevice->deleteStream(mCallbackStreamId);
375 mCallbackStreamId = NO_STREAM;
376 }
377
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) {
619 res = updateCallbackStream(params);
620 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] =
638 { mPreviewStreamId, mCallbackStreamId };
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) {
802 res = updateCallbackStream(params);
803 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] =
821 { mPreviewStreamId, mRecordingStreamId, mCallbackStreamId };
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700822 res = mRecordingRequest.update(
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700823 ANDROID_REQUEST_OUTPUT_STREAMS,
824 outputStreams, 3);
825 } else {
826 uint8_t outputStreams[2] = { mPreviewStreamId, mRecordingStreamId };
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700827 res = mRecordingRequest.update(
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700828 ANDROID_REQUEST_OUTPUT_STREAMS,
829 outputStreams, 2);
830 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700831 if (res != OK) {
832 ALOGE("%s: Camera %d: Unable to set up recording request: %s (%d)",
833 __FUNCTION__, mCameraId, strerror(-res), res);
834 return res;
835 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700836 res = mRecordingRequest.sort();
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700837 if (res != OK) {
838 ALOGE("%s: Camera %d: Error sorting recording request: %s (%d)",
839 __FUNCTION__, mCameraId, strerror(-res), res);
840 return res;
841 }
842
843 res = mDevice->setStreamingRequest(mRecordingRequest);
844 if (res != OK) {
845 ALOGE("%s: Camera %d: Unable to set recording request to start "
846 "recording: %s (%d)", __FUNCTION__, mCameraId,
847 strerror(-res), res);
848 return res;
849 }
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700850 if (params.state < Parameters::RECORD) {
851 params.state = Parameters::RECORD;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700852 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700853
854 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700855}
856
857void Camera2Client::stopRecording() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700858 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700859 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700860 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700861 SharedParameters::Lock l(mParameters);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700862
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700863 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700864 if ( (res = checkPid(__FUNCTION__) ) != OK) return;
865
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700866 switch (l.mParameters.state) {
867 case Parameters::RECORD:
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700868 // OK to stop
869 break;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700870 case Parameters::STOPPED:
871 case Parameters::PREVIEW:
872 case Parameters::STILL_CAPTURE:
873 case Parameters::VIDEO_SNAPSHOT:
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700874 default:
875 ALOGE("%s: Camera %d: Can't stop recording in state %s",
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700876 __FUNCTION__, mCameraId,
877 Parameters::getStateName(l.mParameters.state));
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700878 return;
879 };
880
881 // Back to preview. Since record can only be reached through preview,
882 // all preview stream setup should be up to date.
883 res = mDevice->setStreamingRequest(mPreviewRequest);
884 if (res != OK) {
885 ALOGE("%s: Camera %d: Unable to switch back to preview request: "
886 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
887 return;
888 }
889
890 // TODO: Should recording heap be freed? Can't do it yet since requests
891 // could still be in flight.
892
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700893 l.mParameters.state = Parameters::PREVIEW;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700894}
895
896bool Camera2Client::recordingEnabled() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700897 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700898 Mutex::Autolock icl(mICameraLock);
James Dong8da4cd72012-08-04 19:58:07 -0700899
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700900 if ( checkPid(__FUNCTION__) != OK) return false;
901
James Dong8da4cd72012-08-04 19:58:07 -0700902 return recordingEnabledL();
903}
904
905bool Camera2Client::recordingEnabledL() {
906 ATRACE_CALL();
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700907 SharedParameters::Lock l(mParameters);
James Dong8da4cd72012-08-04 19:58:07 -0700908
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700909 return (l.mParameters.state == Parameters::RECORD
910 || l.mParameters.state == Parameters::VIDEO_SNAPSHOT);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700911}
912
913void Camera2Client::releaseRecordingFrame(const sp<IMemory>& mem) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700914 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700915 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700916 status_t res;
917 if ( checkPid(__FUNCTION__) != OK) return;
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -0700918
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700919 SharedParameters::Lock l(mParameters);
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -0700920
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700921 // Make sure this is for the current heap
922 ssize_t offset;
923 size_t size;
924 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
925 if (heap->getHeapID() != mRecordingHeap->mHeap->getHeapID()) {
926 ALOGW("%s: Camera %d: Mismatched heap ID, ignoring release "
927 "(got %x, expected %x)", __FUNCTION__, mCameraId,
928 heap->getHeapID(), mRecordingHeap->mHeap->getHeapID());
929 return;
930 }
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700931 uint8_t *data = (uint8_t*)heap->getBase() + offset;
932 uint32_t type = *(uint32_t*)data;
933 if (type != kMetadataBufferTypeGrallocSource) {
934 ALOGE("%s: Camera %d: Recording frame type invalid (got %x, expected %x)",
935 __FUNCTION__, mCameraId, type, kMetadataBufferTypeGrallocSource);
936 return;
937 }
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -0700938
939 // Release the buffer back to the recording queue
940
941 buffer_handle_t imgHandle = *(buffer_handle_t*)(data + 4);
942
943 size_t itemIndex;
944 for (itemIndex = 0; itemIndex < mRecordingBuffers.size(); itemIndex++) {
945 const BufferItemConsumer::BufferItem item = mRecordingBuffers[itemIndex];
946 if (item.mBuf != BufferItemConsumer::INVALID_BUFFER_SLOT &&
947 item.mGraphicBuffer->handle == imgHandle) {
948 break;
949 }
950 }
951 if (itemIndex == mRecordingBuffers.size()) {
952 ALOGE("%s: Camera %d: Can't find buffer_handle_t %p in list of "
953 "outstanding buffers", __FUNCTION__, mCameraId, imgHandle);
954 return;
955 }
956
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700957 ALOGV("%s: Camera %d: Freeing buffer_handle_t %p", __FUNCTION__, mCameraId,
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -0700958 imgHandle);
959
960 res = mRecordingConsumer->releaseBuffer(mRecordingBuffers[itemIndex]);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700961 if (res != OK) {
962 ALOGE("%s: Camera %d: Unable to free recording frame (buffer_handle_t: %p):"
963 "%s (%d)",
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -0700964 __FUNCTION__, mCameraId, imgHandle, strerror(-res), res);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700965 return;
966 }
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -0700967 mRecordingBuffers.replaceAt(itemIndex);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700968
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700969 mRecordingHeapFree++;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700970}
971
972status_t Camera2Client::autoFocus() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700973 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700974 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700975 status_t res;
976 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
977
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700978 int triggerId;
979 {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700980 SharedParameters::Lock l(mParameters);
981 l.mParameters.currentAfTriggerId = ++l.mParameters.afTriggerCounter;
982 triggerId = l.mParameters.currentAfTriggerId;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700983 }
984
985 mDevice->triggerAutofocus(triggerId);
986
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700987 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700988}
989
990status_t Camera2Client::cancelAutoFocus() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700991 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700992 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700993 status_t res;
994 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
995
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700996 int triggerId;
997 {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700998 SharedParameters::Lock l(mParameters);
999 triggerId = ++l.mParameters.afTriggerCounter;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001000 }
1001
1002 mDevice->triggerCancelAutofocus(triggerId);
1003
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001004 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001005}
1006
1007status_t Camera2Client::takePicture(int msgType) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001008 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001009 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001010 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001011 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001012
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001013 SharedParameters::Lock l(mParameters);
1014 switch (l.mParameters.state) {
1015 case Parameters::DISCONNECTED:
1016 case Parameters::STOPPED:
1017 case Parameters::WAITING_FOR_PREVIEW_WINDOW:
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001018 ALOGE("%s: Camera %d: Cannot take picture without preview enabled",
1019 __FUNCTION__, mCameraId);
1020 return INVALID_OPERATION;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001021 case Parameters::PREVIEW:
1022 case Parameters::RECORD:
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001023 // Good to go for takePicture
1024 break;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001025 case Parameters::STILL_CAPTURE:
1026 case Parameters::VIDEO_SNAPSHOT:
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001027 ALOGE("%s: Camera %d: Already taking a picture",
1028 __FUNCTION__, mCameraId);
1029 return INVALID_OPERATION;
1030 }
1031
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001032 ALOGV("%s: Camera %d: Starting picture capture", __FUNCTION__, mCameraId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001033
Eino-Ville Talvala177bd342012-08-28 01:25:43 -07001034 res = mCaptureProcessor->updateStream(l.mParameters);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001035 if (res != OK) {
1036 ALOGE("%s: Camera %d: Can't set up still image stream: %s (%d)",
1037 __FUNCTION__, mCameraId, strerror(-res), res);
1038 return res;
1039 }
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001040
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001041 if (mCaptureRequest.entryCount() == 0) {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001042 res = updateCaptureRequest(l.mParameters);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -07001043 if (res != OK) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001044 ALOGE("%s: Camera %d: Can't create still image capture request: "
1045 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -07001046 return res;
1047 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001048 }
1049
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001050 bool callbacksEnabled = l.mParameters.previewCallbackFlags &
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001051 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001052 bool recordingEnabled = (l.mParameters.state == Parameters::RECORD);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001053
Eino-Ville Talvala177bd342012-08-28 01:25:43 -07001054 int captureStreamId = mCaptureProcessor->getStreamId();
1055
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001056 int streamSwitch = (callbacksEnabled ? 0x2 : 0x0) +
1057 (recordingEnabled ? 0x1 : 0x0);
1058 switch ( streamSwitch ) {
1059 case 0: { // No recording, callbacks
Eino-Ville Talvala177bd342012-08-28 01:25:43 -07001060 uint8_t streamIds[2] = { mPreviewStreamId, captureStreamId };
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001061 res = mCaptureRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS,
1062 streamIds, 2);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001063 break;
1064 }
1065 case 1: { // Recording
1066 uint8_t streamIds[3] = { mPreviewStreamId, mRecordingStreamId,
Eino-Ville Talvala177bd342012-08-28 01:25:43 -07001067 captureStreamId };
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001068 res = mCaptureRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS,
1069 streamIds, 3);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001070 break;
1071 }
1072 case 2: { // Callbacks
1073 uint8_t streamIds[3] = { mPreviewStreamId, mCallbackStreamId,
Eino-Ville Talvala177bd342012-08-28 01:25:43 -07001074 captureStreamId };
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 3: { // Both
1080 uint8_t streamIds[4] = { mPreviewStreamId, mCallbackStreamId,
Eino-Ville Talvala177bd342012-08-28 01:25:43 -07001081 mRecordingStreamId, captureStreamId };
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001082 res = mCaptureRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS,
1083 streamIds, 4);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001084 break;
1085 }
1086 };
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001087 if (res != OK) {
1088 ALOGE("%s: Camera %d: Unable to set up still image capture request: "
1089 "%s (%d)",
1090 __FUNCTION__, mCameraId, strerror(-res), res);
1091 return res;
1092 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001093 res = mCaptureRequest.sort();
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001094 if (res != OK) {
1095 ALOGE("%s: Camera %d: Unable to sort capture request: %s (%d)",
1096 __FUNCTION__, mCameraId, strerror(-res), res);
1097 return res;
1098 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001099
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001100 CameraMetadata captureCopy = mCaptureRequest;
1101 if (captureCopy.entryCount() == 0) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001102 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device",
1103 __FUNCTION__, mCameraId);
1104 return NO_MEMORY;
1105 }
1106
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001107 if (l.mParameters.state == Parameters::PREVIEW) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001108 res = mDevice->clearStreamingRequest();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001109 if (res != OK) {
1110 ALOGE("%s: Camera %d: Unable to stop preview for still capture: "
1111 "%s (%d)",
1112 __FUNCTION__, mCameraId, strerror(-res), res);
1113 return res;
1114 }
1115 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001116 // TODO: Capture should be atomic with setStreamingRequest here
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001117 res = mDevice->capture(captureCopy);
1118 if (res != OK) {
1119 ALOGE("%s: Camera %d: Unable to submit still image capture request: "
1120 "%s (%d)",
1121 __FUNCTION__, mCameraId, strerror(-res), res);
1122 return res;
1123 }
1124
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001125 switch (l.mParameters.state) {
1126 case Parameters::PREVIEW:
1127 l.mParameters.state = Parameters::STILL_CAPTURE;
1128 res = commandStopFaceDetectionL(l.mParameters);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001129 if (res != OK) {
1130 ALOGE("%s: Camera %d: Unable to stop face detection for still capture",
1131 __FUNCTION__, mCameraId);
1132 return res;
1133 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001134 break;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001135 case Parameters::RECORD:
1136 l.mParameters.state = Parameters::VIDEO_SNAPSHOT;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001137 break;
1138 default:
1139 ALOGE("%s: Camera %d: Unknown state for still capture!",
1140 __FUNCTION__, mCameraId);
1141 return INVALID_OPERATION;
1142 }
1143
1144 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001145}
1146
1147status_t Camera2Client::setParameters(const String8& params) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001148 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -07001149 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001150 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001151 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001152 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
1153
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001154 SharedParameters::Lock l(mParameters);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001155
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001156 res = l.mParameters.set(params);
1157 if (res != OK) return res;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001158
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001159 res = updateRequests(l.mParameters);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001160
1161 return res;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001162}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001163
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001164String8 Camera2Client::getParameters() const {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001165 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001166 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001167 if ( checkPid(__FUNCTION__) != OK) return String8();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001168
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001169 SharedParameters::ReadLock l(mParameters);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001170
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001171 // TODO: Deal with focus distances
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001172 return l.mParameters.paramsFlattened;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001173}
1174
1175status_t Camera2Client::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001176 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001177 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001178 status_t res;
1179 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001180
1181 ALOGV("%s: Camera %d: Command %d (%d, %d)", __FUNCTION__, mCameraId,
1182 cmd, arg1, arg2);
1183
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001184 switch (cmd) {
1185 case CAMERA_CMD_START_SMOOTH_ZOOM:
1186 return commandStartSmoothZoomL();
1187 case CAMERA_CMD_STOP_SMOOTH_ZOOM:
1188 return commandStopSmoothZoomL();
1189 case CAMERA_CMD_SET_DISPLAY_ORIENTATION:
1190 return commandSetDisplayOrientationL(arg1);
1191 case CAMERA_CMD_ENABLE_SHUTTER_SOUND:
1192 return commandEnableShutterSoundL(arg1 == 1);
1193 case CAMERA_CMD_PLAY_RECORDING_SOUND:
1194 return commandPlayRecordingSoundL();
1195 case CAMERA_CMD_START_FACE_DETECTION:
1196 return commandStartFaceDetectionL(arg1);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001197 case CAMERA_CMD_STOP_FACE_DETECTION: {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001198 SharedParameters::Lock l(mParameters);
1199 return commandStopFaceDetectionL(l.mParameters);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001200 }
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001201 case CAMERA_CMD_ENABLE_FOCUS_MOVE_MSG:
1202 return commandEnableFocusMoveMsgL(arg1 == 1);
1203 case CAMERA_CMD_PING:
1204 return commandPingL();
1205 case CAMERA_CMD_SET_VIDEO_BUFFER_COUNT:
1206 return commandSetVideoBufferCountL(arg1);
1207 default:
1208 ALOGE("%s: Unknown command %d (arguments %d, %d)",
1209 __FUNCTION__, cmd, arg1, arg2);
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001210 return BAD_VALUE;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001211 }
1212}
James Dong983cf232012-08-01 16:39:55 -07001213
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001214status_t Camera2Client::commandStartSmoothZoomL() {
1215 ALOGE("%s: Unimplemented!", __FUNCTION__);
1216 return OK;
1217}
James Dong983cf232012-08-01 16:39:55 -07001218
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001219status_t Camera2Client::commandStopSmoothZoomL() {
1220 ALOGE("%s: Unimplemented!", __FUNCTION__);
1221 return OK;
1222}
James Dong983cf232012-08-01 16:39:55 -07001223
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001224status_t Camera2Client::commandSetDisplayOrientationL(int degrees) {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001225 int transform = Parameters::degToTransform(degrees,
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001226 mCameraFacing == CAMERA_FACING_FRONT);
1227 if (transform == -1) {
1228 ALOGE("%s: Camera %d: Error setting %d as display orientation value",
1229 __FUNCTION__, mCameraId, degrees);
1230 return BAD_VALUE;
1231 }
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001232 SharedParameters::Lock l(mParameters);
1233 if (transform != l.mParameters.previewTransform &&
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001234 mPreviewStreamId != NO_STREAM) {
1235 mDevice->setStreamTransform(mPreviewStreamId, transform);
1236 }
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001237 l.mParameters.previewTransform = transform;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001238 return OK;
1239}
1240
1241status_t Camera2Client::commandEnableShutterSoundL(bool enable) {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001242 SharedParameters::Lock l(mParameters);
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001243 if (enable) {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001244 l.mParameters.playShutterSound = true;
James Dong983cf232012-08-01 16:39:55 -07001245 return OK;
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001246 }
1247
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001248 // Disabling shutter sound may not be allowed. In that case only
1249 // allow the mediaserver process to disable the sound.
1250 char value[PROPERTY_VALUE_MAX];
1251 property_get("ro.camera.sound.forced", value, "0");
1252 if (strncmp(value, "0", 2) != 0) {
1253 // Disabling shutter sound is not allowed. Deny if the current
1254 // process is not mediaserver.
1255 if (getCallingPid() != getpid()) {
1256 ALOGE("Failed to disable shutter sound. Permission denied (pid %d)",
1257 getCallingPid());
1258 return PERMISSION_DENIED;
1259 }
1260 }
1261
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001262 l.mParameters.playShutterSound = false;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001263 return OK;
1264}
1265
1266status_t Camera2Client::commandPlayRecordingSoundL() {
1267 mCameraService->playSound(CameraService::SOUND_RECORDING);
1268 return OK;
1269}
1270
1271status_t Camera2Client::commandStartFaceDetectionL(int type) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001272 ALOGV("%s: Camera %d: Starting face detection",
1273 __FUNCTION__, mCameraId);
1274 status_t res;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001275 SharedParameters::Lock l(mParameters);
1276 switch (l.mParameters.state) {
1277 case Parameters::DISCONNECTED:
1278 case Parameters::STOPPED:
1279 case Parameters::WAITING_FOR_PREVIEW_WINDOW:
1280 case Parameters::STILL_CAPTURE:
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001281 ALOGE("%s: Camera %d: Cannot start face detection without preview active",
1282 __FUNCTION__, mCameraId);
1283 return INVALID_OPERATION;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001284 case Parameters::PREVIEW:
1285 case Parameters::RECORD:
1286 case Parameters::VIDEO_SNAPSHOT:
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001287 // Good to go for starting face detect
1288 break;
1289 }
1290 // Ignoring type
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001291 if (l.mParameters.fastInfo.bestFaceDetectMode ==
1292 ANDROID_STATS_FACE_DETECTION_OFF) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001293 ALOGE("%s: Camera %d: Face detection not supported",
1294 __FUNCTION__, mCameraId);
1295 return INVALID_OPERATION;
1296 }
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001297 if (l.mParameters.enableFaceDetect) return OK;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001298
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001299 l.mParameters.enableFaceDetect = true;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001300
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001301 res = updateRequests(l.mParameters);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001302
1303 return res;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001304}
1305
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001306status_t Camera2Client::commandStopFaceDetectionL(Parameters &params) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001307 status_t res = OK;
1308 ALOGV("%s: Camera %d: Stopping face detection",
1309 __FUNCTION__, mCameraId);
1310
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001311 if (!params.enableFaceDetect) return OK;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001312
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001313 params.enableFaceDetect = false;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001314
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001315 if (params.state == Parameters::PREVIEW
1316 || params.state == Parameters::RECORD
1317 || params.state == Parameters::VIDEO_SNAPSHOT) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001318 res = updateRequests(params);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001319 }
1320
1321 return res;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001322}
1323
1324status_t Camera2Client::commandEnableFocusMoveMsgL(bool enable) {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001325 SharedParameters::Lock l(mParameters);
1326 l.mParameters.enableFocusMoveMessages = enable;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001327
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001328 return OK;
1329}
1330
1331status_t Camera2Client::commandPingL() {
1332 // Always ping back if access is proper and device is alive
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001333 SharedParameters::Lock l(mParameters);
1334 if (l.mParameters.state != Parameters::DISCONNECTED) {
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001335 return OK;
1336 } else {
1337 return NO_INIT;
1338 }
1339}
1340
1341status_t Camera2Client::commandSetVideoBufferCountL(size_t count) {
James Dong8da4cd72012-08-04 19:58:07 -07001342 if (recordingEnabledL()) {
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001343 ALOGE("%s: Camera %d: Error setting video buffer count after "
1344 "recording was started", __FUNCTION__, mCameraId);
1345 return INVALID_OPERATION;
1346 }
1347
1348 // 32 is the current upper limit on the video buffer count for BufferQueue
1349 if (count > 32) {
1350 ALOGE("%s: Camera %d: Error setting %d as video buffer count value",
1351 __FUNCTION__, mCameraId, count);
1352 return BAD_VALUE;
1353 }
1354
1355 // Need to reallocate memory for heap
1356 if (mRecordingHeapCount != count) {
1357 if (mRecordingHeap != 0) {
1358 mRecordingHeap.clear();
1359 mRecordingHeap = NULL;
1360 }
1361 mRecordingHeapCount = count;
1362 }
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001363
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001364 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001365}
1366
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001367/** Device-related methods */
1368
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -07001369void Camera2Client::notifyError(int errorCode, int arg1, int arg2) {
1370 ALOGE("Error condition %d reported by HAL, arguments %d, %d", errorCode, arg1, arg2);
1371}
1372
1373void Camera2Client::notifyShutter(int frameNumber, nsecs_t timestamp) {
1374 ALOGV("%s: Shutter notification for frame %d at time %lld", __FUNCTION__,
1375 frameNumber, timestamp);
1376}
1377
1378void Camera2Client::notifyAutoFocus(uint8_t newState, int triggerId) {
1379 ALOGV("%s: Autofocus state now %d, last trigger %d",
1380 __FUNCTION__, newState, triggerId);
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001381 bool sendCompletedMessage = false;
1382 bool sendMovingMessage = false;
1383
1384 bool success = false;
1385 bool afInMotion = false;
1386 {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001387 SharedParameters::Lock l(mParameters);
1388 switch (l.mParameters.focusMode) {
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001389 case Parameters::FOCUS_MODE_AUTO:
1390 case Parameters::FOCUS_MODE_MACRO:
1391 // Don't send notifications upstream if they're not for the current AF
1392 // trigger. For example, if cancel was called in between, or if we
1393 // already sent a notification about this AF call.
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001394 if (triggerId != l.mParameters.currentAfTriggerId) break;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001395 switch (newState) {
1396 case ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED:
1397 success = true;
1398 // no break
1399 case ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
1400 sendCompletedMessage = true;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001401 l.mParameters.currentAfTriggerId = -1;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001402 break;
1403 case ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN:
1404 // Just starting focusing, ignore
1405 break;
1406 case ANDROID_CONTROL_AF_STATE_INACTIVE:
1407 case ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN:
1408 case ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED:
1409 default:
1410 // Unexpected in AUTO/MACRO mode
1411 ALOGE("%s: Unexpected AF state transition in AUTO/MACRO mode: %d",
1412 __FUNCTION__, newState);
1413 break;
1414 }
1415 break;
1416 case Parameters::FOCUS_MODE_CONTINUOUS_VIDEO:
1417 case Parameters::FOCUS_MODE_CONTINUOUS_PICTURE:
1418 switch (newState) {
1419 case ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED:
1420 success = true;
1421 // no break
1422 case ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
1423 // Don't send notifications upstream if they're not for
1424 // the current AF trigger. For example, if cancel was
1425 // called in between, or if we already sent a
1426 // notification about this AF call.
1427 // Send both a 'AF done' callback and a 'AF move' callback
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001428 if (triggerId != l.mParameters.currentAfTriggerId) break;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001429 sendCompletedMessage = true;
1430 afInMotion = false;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001431 if (l.mParameters.enableFocusMoveMessages &&
1432 l.mParameters.afInMotion) {
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001433 sendMovingMessage = true;
1434 }
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001435 l.mParameters.currentAfTriggerId = -1;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001436 break;
1437 case ANDROID_CONTROL_AF_STATE_INACTIVE:
1438 // Cancel was called, or we switched state; care if
1439 // currently moving
1440 afInMotion = false;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001441 if (l.mParameters.enableFocusMoveMessages &&
1442 l.mParameters.afInMotion) {
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001443 sendMovingMessage = true;
1444 }
1445 break;
1446 case ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN:
1447 // Start passive scan, inform upstream
1448 afInMotion = true;
1449 // no break
1450 case ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED:
1451 // Stop passive scan, inform upstream
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001452 if (l.mParameters.enableFocusMoveMessages) {
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001453 sendMovingMessage = true;
1454 }
1455 break;
1456 }
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001457 l.mParameters.afInMotion = afInMotion;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001458 break;
1459 case Parameters::FOCUS_MODE_EDOF:
1460 case Parameters::FOCUS_MODE_INFINITY:
1461 case Parameters::FOCUS_MODE_FIXED:
1462 default:
1463 if (newState != ANDROID_CONTROL_AF_STATE_INACTIVE) {
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -07001464 ALOGE("%s: Unexpected AF state change %d "
1465 "(ID %d) in focus mode %d",
1466 __FUNCTION__, newState, triggerId,
1467 l.mParameters.focusMode);
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001468 }
1469 }
1470 }
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001471 if (sendMovingMessage) {
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -07001472 SharedCameraClient::Lock l(mSharedCameraClient);
1473 if (l.mCameraClient != 0) {
1474 l.mCameraClient->notifyCallback(CAMERA_MSG_FOCUS_MOVE,
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001475 afInMotion ? 1 : 0, 0);
1476 }
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001477 }
Eino-Ville Talvala603b12e2012-08-08 09:25:58 -07001478 if (sendCompletedMessage) {
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -07001479 SharedCameraClient::Lock l(mSharedCameraClient);
1480 if (l.mCameraClient != 0) {
1481 l.mCameraClient->notifyCallback(CAMERA_MSG_FOCUS,
1482 success ? 1 : 0, 0);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001483 }
Eino-Ville Talvala603b12e2012-08-08 09:25:58 -07001484 }
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -07001485}
1486
1487void Camera2Client::notifyAutoExposure(uint8_t newState, int triggerId) {
1488 ALOGV("%s: Autoexposure state now %d, last trigger %d",
1489 __FUNCTION__, newState, triggerId);
1490}
1491
1492void Camera2Client::notifyAutoWhitebalance(uint8_t newState, int triggerId) {
1493 ALOGV("%s: Auto-whitebalance state now %d, last trigger %d",
1494 __FUNCTION__, newState, triggerId);
1495}
1496
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -07001497int Camera2Client::getCameraId() {
1498 return mCameraId;
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -07001499}
1500
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -07001501const sp<Camera2Device>& Camera2Client::getCameraDevice() {
1502 return mDevice;
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -07001503}
1504
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -07001505camera2::SharedParameters& Camera2Client::getParameters() {
1506 return mParameters;
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -07001507}
1508
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -07001509Camera2Client::SharedCameraClient::Lock::Lock(SharedCameraClient &client):
1510 mCameraClient(client.mCameraClient),
1511 mSharedClient(client) {
1512 mSharedClient.mCameraClientLock.lock();
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -07001513}
1514
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -07001515Camera2Client::SharedCameraClient::Lock::~Lock() {
1516 mSharedClient.mCameraClientLock.unlock();
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001517}
1518
Eino-Ville Talvala177bd342012-08-28 01:25:43 -07001519Camera2Client::SharedCameraClient::SharedCameraClient(const sp<ICameraClient>&client):
1520 mCameraClient(client) {
1521}
1522
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -07001523Camera2Client::SharedCameraClient& Camera2Client::SharedCameraClient::operator=(
1524 const sp<ICameraClient>&client) {
1525 Mutex::Autolock l(mCameraClientLock);
1526 mCameraClient = client;
1527 return *this;
1528}
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001529
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -07001530void Camera2Client::SharedCameraClient::clear() {
1531 Mutex::Autolock l(mCameraClientLock);
1532 mCameraClient.clear();
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001533}
1534
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001535void Camera2Client::onCallbackAvailable() {
1536 ATRACE_CALL();
1537 status_t res;
1538 ALOGV("%s: Camera %d: Preview callback available", __FUNCTION__, mCameraId);
1539
1540 int callbackHeapId;
1541 sp<Camera2Heap> callbackHeap;
1542 size_t heapIdx;
1543
1544 CpuConsumer::LockedBuffer imgBuffer;
1545 ALOGV("%s: Getting buffer", __FUNCTION__);
1546 res = mCallbackConsumer->lockNextBuffer(&imgBuffer);
1547 if (res != OK) {
1548 ALOGE("%s: Camera %d: Error receiving next callback buffer: "
1549 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
1550 return;
1551 }
1552
1553 {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001554 SharedParameters::Lock l(mParameters);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001555
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001556 if ( l.mParameters.state != Parameters::PREVIEW
1557 && l.mParameters.state != Parameters::RECORD
1558 && l.mParameters.state != Parameters::VIDEO_SNAPSHOT) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001559 ALOGV("%s: Camera %d: No longer streaming",
1560 __FUNCTION__, mCameraId);
1561 mCallbackConsumer->unlockBuffer(imgBuffer);
1562 return;
1563 }
1564
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001565 if (! (l.mParameters.previewCallbackFlags &
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001566 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) ) {
1567 ALOGV("%s: No longer enabled, dropping", __FUNCTION__);
1568 mCallbackConsumer->unlockBuffer(imgBuffer);
1569 return;
1570 }
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001571 if ((l.mParameters.previewCallbackFlags &
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001572 CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) &&
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001573 !l.mParameters.previewCallbackOneShot) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001574 ALOGV("%s: One shot mode, already sent, dropping", __FUNCTION__);
1575 mCallbackConsumer->unlockBuffer(imgBuffer);
1576 return;
1577 }
1578
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001579 if (imgBuffer.format != l.mParameters.previewFormat) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001580 ALOGE("%s: Camera %d: Unexpected format for callback: "
1581 "%x, expected %x", __FUNCTION__, mCameraId,
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001582 imgBuffer.format, l.mParameters.previewFormat);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001583 mCallbackConsumer->unlockBuffer(imgBuffer);
1584 return;
1585 }
1586
1587 size_t bufferSize = calculateBufferSize(imgBuffer.width, imgBuffer.height,
1588 imgBuffer.format, imgBuffer.stride);
1589 size_t currentBufferSize = (mCallbackHeap == 0) ?
1590 0 : (mCallbackHeap->mHeap->getSize() / kCallbackHeapCount);
1591 if (bufferSize != currentBufferSize) {
1592 mCallbackHeap.clear();
1593 mCallbackHeap = new Camera2Heap(bufferSize, kCallbackHeapCount,
1594 "Camera2Client::CallbackHeap");
1595 if (mCallbackHeap->mHeap->getSize() == 0) {
1596 ALOGE("%s: Camera %d: Unable to allocate memory for callbacks",
1597 __FUNCTION__, mCameraId);
1598 mCallbackConsumer->unlockBuffer(imgBuffer);
1599 return;
1600 }
1601
1602 mCallbackHeapHead = 0;
1603 mCallbackHeapFree = kCallbackHeapCount;
1604 mCallbackHeapId++;
1605 }
1606
1607 if (mCallbackHeapFree == 0) {
1608 ALOGE("%s: Camera %d: No free callback buffers, dropping frame",
1609 __FUNCTION__, mCameraId);
1610 mCallbackConsumer->unlockBuffer(imgBuffer);
1611 return;
1612 }
1613 heapIdx = mCallbackHeapHead;
1614 callbackHeap = mCallbackHeap;
1615 callbackHeapId = mCallbackHeapId;
1616
1617 mCallbackHeapHead = (mCallbackHeapHead + 1) & kCallbackHeapCount;
1618 mCallbackHeapFree--;
1619
1620 // TODO: Get rid of this memcpy by passing the gralloc queue all the way
1621 // to app
1622
1623 ssize_t offset;
1624 size_t size;
1625 sp<IMemoryHeap> heap =
1626 mCallbackHeap->mBuffers[heapIdx]->getMemory(&offset,
1627 &size);
1628 uint8_t *data = (uint8_t*)heap->getBase() + offset;
1629 memcpy(data, imgBuffer.data, bufferSize);
1630
1631 ALOGV("%s: Freeing buffer", __FUNCTION__);
1632 mCallbackConsumer->unlockBuffer(imgBuffer);
1633
1634 // In one-shot mode, stop sending callbacks after the first one
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001635 if (l.mParameters.previewCallbackFlags &
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001636 CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) {
1637 ALOGV("%s: clearing oneshot", __FUNCTION__);
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001638 l.mParameters.previewCallbackOneShot = false;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001639 }
1640 }
1641
1642 // Call outside parameter lock to allow re-entrancy from notification
1643 {
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -07001644 SharedCameraClient::Lock l(mSharedCameraClient);
1645 if (l.mCameraClient != 0) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001646 ALOGV("%s: Camera %d: Invoking client data callback",
1647 __FUNCTION__, mCameraId);
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -07001648 l.mCameraClient->dataCallback(CAMERA_MSG_PREVIEW_FRAME,
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001649 callbackHeap->mBuffers[heapIdx], NULL);
1650 }
1651 }
1652
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001653 SharedParameters::Lock l(mParameters);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001654 // Only increment free if we're still using the same heap
1655 if (mCallbackHeapId == callbackHeapId) {
1656 mCallbackHeapFree++;
1657 }
1658
1659 ALOGV("%s: exit", __FUNCTION__);
1660}
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001661
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001662void Camera2Client::onRecordingFrameAvailable() {
1663 ATRACE_CALL();
1664 status_t res;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001665 sp<Camera2Heap> recordingHeap;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001666 size_t heapIdx = 0;
1667 nsecs_t timestamp;
1668 {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001669 SharedParameters::Lock l(mParameters);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001670
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07001671 BufferItemConsumer::BufferItem imgBuffer;
1672 res = mRecordingConsumer->acquireBuffer(&imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001673 if (res != OK) {
1674 ALOGE("%s: Camera %d: Error receiving recording buffer: %s (%d)",
1675 __FUNCTION__, mCameraId, strerror(-res), res);
1676 return;
1677 }
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07001678 timestamp = imgBuffer.mTimestamp;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001679
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001680 mRecordingFrameCount++;
1681 ALOGV("OnRecordingFrame: Frame %d", mRecordingFrameCount);
1682
1683 // TODO: Signal errors here upstream
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001684 if (l.mParameters.state != Parameters::RECORD &&
1685 l.mParameters.state != Parameters::VIDEO_SNAPSHOT) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001686 ALOGV("%s: Camera %d: Discarding recording image buffers received after "
1687 "recording done",
1688 __FUNCTION__, mCameraId);
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07001689 mRecordingConsumer->releaseBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001690 return;
1691 }
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001692
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001693 if (mRecordingHeap == 0) {
1694 const size_t bufferSize = 4 + sizeof(buffer_handle_t);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001695 ALOGV("%s: Camera %d: Creating recording heap with %d buffers of "
1696 "size %d bytes", __FUNCTION__, mCameraId,
James Dong983cf232012-08-01 16:39:55 -07001697 mRecordingHeapCount, bufferSize);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001698
James Dong983cf232012-08-01 16:39:55 -07001699 mRecordingHeap = new Camera2Heap(bufferSize, mRecordingHeapCount,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001700 "Camera2Client::RecordingHeap");
1701 if (mRecordingHeap->mHeap->getSize() == 0) {
1702 ALOGE("%s: Camera %d: Unable to allocate memory for recording",
1703 __FUNCTION__, mCameraId);
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07001704 mRecordingConsumer->releaseBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001705 return;
1706 }
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07001707 for (size_t i = 0; i < mRecordingBuffers.size(); i++) {
1708 if (mRecordingBuffers[i].mBuf !=
1709 BufferItemConsumer::INVALID_BUFFER_SLOT) {
1710 ALOGE("%s: Camera %d: Non-empty recording buffers list!",
1711 __FUNCTION__, mCameraId);
1712 }
1713 }
1714 mRecordingBuffers.clear();
1715 mRecordingBuffers.setCapacity(mRecordingHeapCount);
1716 mRecordingBuffers.insertAt(0, mRecordingHeapCount);
1717
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001718 mRecordingHeapHead = 0;
James Dong983cf232012-08-01 16:39:55 -07001719 mRecordingHeapFree = mRecordingHeapCount;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001720 }
1721
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001722 if ( mRecordingHeapFree == 0) {
1723 ALOGE("%s: Camera %d: No free recording buffers, dropping frame",
1724 __FUNCTION__, mCameraId);
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07001725 mRecordingConsumer->releaseBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001726 return;
1727 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001728
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001729 heapIdx = mRecordingHeapHead;
James Dong983cf232012-08-01 16:39:55 -07001730 mRecordingHeapHead = (mRecordingHeapHead + 1) % mRecordingHeapCount;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001731 mRecordingHeapFree--;
1732
1733 ALOGV("%s: Camera %d: Timestamp %lld",
1734 __FUNCTION__, mCameraId, timestamp);
1735
1736 ssize_t offset;
1737 size_t size;
1738 sp<IMemoryHeap> heap =
1739 mRecordingHeap->mBuffers[heapIdx]->getMemory(&offset,
1740 &size);
1741
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001742 uint8_t *data = (uint8_t*)heap->getBase() + offset;
1743 uint32_t type = kMetadataBufferTypeGrallocSource;
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07001744 *((uint32_t*)data) = type;
1745 *((buffer_handle_t*)(data + 4)) = imgBuffer.mGraphicBuffer->handle;
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001746 ALOGV("%s: Camera %d: Sending out buffer_handle_t %p",
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07001747 __FUNCTION__, mCameraId, imgBuffer.mGraphicBuffer->handle);
1748 mRecordingBuffers.replaceAt(imgBuffer, heapIdx);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001749 recordingHeap = mRecordingHeap;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001750 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001751
1752 // Call outside locked parameters to allow re-entrancy from notification
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -07001753 SharedCameraClient::Lock l(mSharedCameraClient);
1754 if (l.mCameraClient != 0) {
1755 l.mCameraClient->dataCallbackTimestamp(timestamp,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001756 CAMERA_MSG_VIDEO_FRAME,
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001757 recordingHeap->mBuffers[heapIdx]);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001758 }
1759}
1760
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001761/** Utility methods */
1762
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001763status_t Camera2Client::updateRequests(const Parameters &params) {
1764 status_t res;
1765
1766 res = updatePreviewRequest(params);
1767 if (res != OK) {
1768 ALOGE("%s: Camera %d: Unable to update preview request: %s (%d)",
1769 __FUNCTION__, mCameraId, strerror(-res), res);
1770 return res;
1771 }
1772 res = updateCaptureRequest(params);
1773 if (res != OK) {
1774 ALOGE("%s: Camera %d: Unable to update capture request: %s (%d)",
1775 __FUNCTION__, mCameraId, strerror(-res), res);
1776 return res;
1777 }
1778
1779 res = updateRecordingRequest(params);
1780 if (res != OK) {
1781 ALOGE("%s: Camera %d: Unable to update recording request: %s (%d)",
1782 __FUNCTION__, mCameraId, strerror(-res), res);
1783 return res;
1784 }
1785
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001786 if (params.state == Parameters::PREVIEW) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001787 res = mDevice->setStreamingRequest(mPreviewRequest);
1788 if (res != OK) {
1789 ALOGE("%s: Camera %d: Error streaming new preview request: %s (%d)",
1790 __FUNCTION__, mCameraId, strerror(-res), res);
1791 return res;
1792 }
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001793 } else if (params.state == Parameters::RECORD ||
1794 params.state == Parameters::VIDEO_SNAPSHOT) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001795 res = mDevice->setStreamingRequest(mRecordingRequest);
1796 if (res != OK) {
1797 ALOGE("%s: Camera %d: Error streaming new record request: %s (%d)",
1798 __FUNCTION__, mCameraId, strerror(-res), res);
1799 return res;
1800 }
1801 }
1802 return res;
1803}
1804
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001805status_t Camera2Client::updatePreviewStream(const Parameters &params) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001806 ATRACE_CALL();
1807 status_t res;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001808
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001809 if (mPreviewStreamId != NO_STREAM) {
1810 // Check if stream parameters have to change
1811 uint32_t currentWidth, currentHeight;
1812 res = mDevice->getStreamInfo(mPreviewStreamId,
1813 &currentWidth, &currentHeight, 0);
1814 if (res != OK) {
1815 ALOGE("%s: Camera %d: Error querying preview stream info: "
1816 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
1817 return res;
1818 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001819 if (currentWidth != (uint32_t)params.previewWidth ||
1820 currentHeight != (uint32_t)params.previewHeight) {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -07001821 ALOGV("%s: Camera %d: Preview size switch: %d x %d -> %d x %d",
1822 __FUNCTION__, mCameraId, currentWidth, currentHeight,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001823 params.previewWidth, params.previewHeight);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001824 res = mDevice->waitUntilDrained();
1825 if (res != OK) {
1826 ALOGE("%s: Camera %d: Error waiting for preview to drain: "
1827 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
1828 return res;
1829 }
1830 res = mDevice->deleteStream(mPreviewStreamId);
1831 if (res != OK) {
1832 ALOGE("%s: Camera %d: Unable to delete old output stream "
1833 "for preview: %s (%d)", __FUNCTION__, mCameraId,
1834 strerror(-res), res);
1835 return res;
1836 }
1837 mPreviewStreamId = NO_STREAM;
1838 }
1839 }
1840
1841 if (mPreviewStreamId == NO_STREAM) {
1842 res = mDevice->createStream(mPreviewWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001843 params.previewWidth, params.previewHeight,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001844 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0,
1845 &mPreviewStreamId);
1846 if (res != OK) {
1847 ALOGE("%s: Camera %d: Unable to create preview stream: %s (%d)",
1848 __FUNCTION__, mCameraId, strerror(-res), res);
1849 return res;
1850 }
1851 }
1852
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001853 res = mDevice->setStreamTransform(mPreviewStreamId,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001854 params.previewTransform);
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001855 if (res != OK) {
1856 ALOGE("%s: Camera %d: Unable to set preview stream transform: "
1857 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
1858 return res;
1859 }
1860
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001861 return OK;
1862}
1863
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001864status_t Camera2Client::updatePreviewRequest(const Parameters &params) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001865 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001866 status_t res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001867 if (mPreviewRequest.entryCount() == 0) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001868 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
1869 &mPreviewRequest);
1870 if (res != OK) {
1871 ALOGE("%s: Camera %d: Unable to create default preview request: "
1872 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
1873 return res;
1874 }
1875 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001876
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001877 res = updateRequestCommon(&mPreviewRequest, params);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001878 if (res != OK) {
1879 ALOGE("%s: Camera %d: Unable to update common entries of preview "
1880 "request: %s (%d)", __FUNCTION__, mCameraId,
1881 strerror(-res), res);
1882 return res;
1883 }
1884
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001885 return OK;
1886}
1887
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001888status_t Camera2Client::updateCallbackStream(const Parameters &params) {
1889 status_t res;
1890
1891 if (mCallbackConsumer == 0) {
1892 // Create CPU buffer queue endpoint
1893 mCallbackConsumer = new CpuConsumer(kCallbackHeapCount);
1894 mCallbackWaiter = new CallbackWaiter(this);
1895 mCallbackConsumer->setFrameAvailableListener(mCallbackWaiter);
1896 mCallbackConsumer->setName(String8("Camera2Client::CallbackConsumer"));
1897 mCallbackWindow = new SurfaceTextureClient(
1898 mCallbackConsumer->getProducerInterface());
1899 }
1900
1901 if (mCallbackStreamId != NO_STREAM) {
1902 // Check if stream parameters have to change
1903 uint32_t currentWidth, currentHeight, currentFormat;
1904 res = mDevice->getStreamInfo(mCallbackStreamId,
1905 &currentWidth, &currentHeight, &currentFormat);
1906 if (res != OK) {
1907 ALOGE("%s: Camera %d: Error querying callback output stream info: "
1908 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
1909 return res;
1910 }
1911 if (currentWidth != (uint32_t)params.previewWidth ||
1912 currentHeight != (uint32_t)params.previewHeight ||
1913 currentFormat != (uint32_t)params.previewFormat) {
1914 // Since size should only change while preview is not running,
1915 // assuming that all existing use of old callback stream is
1916 // completed.
1917 res = mDevice->deleteStream(mCallbackStreamId);
1918 if (res != OK) {
1919 ALOGE("%s: Camera %d: Unable to delete old output stream "
1920 "for callbacks: %s (%d)", __FUNCTION__, mCameraId,
1921 strerror(-res), res);
1922 return res;
1923 }
1924 mCallbackStreamId = NO_STREAM;
1925 }
1926 }
1927
1928 if (mCallbackStreamId == NO_STREAM) {
1929 ALOGV("Creating callback stream: %d %d format 0x%x",
1930 params.previewWidth, params.previewHeight,
1931 params.previewFormat);
1932 res = mDevice->createStream(mCallbackWindow,
1933 params.previewWidth, params.previewHeight,
1934 params.previewFormat, 0, &mCallbackStreamId);
1935 if (res != OK) {
1936 ALOGE("%s: Camera %d: Can't create output stream for callbacks: "
1937 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
1938 return res;
1939 }
1940 }
1941
1942 return OK;
1943}
1944
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001945status_t Camera2Client::updateCaptureRequest(const Parameters &params) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001946 ATRACE_CALL();
1947 status_t res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001948 if (mCaptureRequest.entryCount() == 0) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001949 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_STILL_CAPTURE,
1950 &mCaptureRequest);
1951 if (res != OK) {
1952 ALOGE("%s: Camera %d: Unable to create default still image request:"
1953 " %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
1954 return res;
1955 }
1956 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001957
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001958 res = updateRequestCommon(&mCaptureRequest, params);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001959 if (res != OK) {
1960 ALOGE("%s: Camera %d: Unable to update common entries of capture "
1961 "request: %s (%d)", __FUNCTION__, mCameraId,
1962 strerror(-res), res);
1963 return res;
1964 }
1965
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001966 res = mCaptureRequest.update(ANDROID_JPEG_THUMBNAIL_SIZE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001967 params.jpegThumbSize, 2);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001968 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001969 res = mCaptureRequest.update(ANDROID_JPEG_THUMBNAIL_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001970 &params.jpegThumbQuality, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001971 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001972 res = mCaptureRequest.update(ANDROID_JPEG_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001973 &params.jpegQuality, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001974 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001975 res = mCaptureRequest.update(
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001976 ANDROID_JPEG_ORIENTATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001977 &params.jpegRotation, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001978 if (res != OK) return res;
1979
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001980 if (params.gpsEnabled) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001981 res = mCaptureRequest.update(
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001982 ANDROID_JPEG_GPS_COORDINATES,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001983 params.gpsCoordinates, 3);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001984 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001985 res = mCaptureRequest.update(
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001986 ANDROID_JPEG_GPS_TIMESTAMP,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001987 &params.gpsTimestamp, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001988 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001989 res = mCaptureRequest.update(
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001990 ANDROID_JPEG_GPS_PROCESSING_METHOD,
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001991 params.gpsProcessingMethod);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001992 if (res != OK) return res;
1993 } else {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001994 res = mCaptureRequest.erase(ANDROID_JPEG_GPS_COORDINATES);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001995 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001996 res = mCaptureRequest.erase(ANDROID_JPEG_GPS_TIMESTAMP);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001997 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001998 res = mCaptureRequest.erase(ANDROID_JPEG_GPS_PROCESSING_METHOD);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001999 if (res != OK) return res;
2000 }
2001
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002002 return OK;
2003}
2004
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002005status_t Camera2Client::updateRecordingRequest(const Parameters &params) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002006 ATRACE_CALL();
2007 status_t res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002008 if (mRecordingRequest.entryCount() == 0) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002009 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_VIDEO_RECORD,
2010 &mRecordingRequest);
2011 if (res != OK) {
2012 ALOGE("%s: Camera %d: Unable to create default recording request:"
2013 " %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2014 return res;
2015 }
2016 }
2017
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002018 res = updateRequestCommon(&mRecordingRequest, params);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002019 if (res != OK) {
2020 ALOGE("%s: Camera %d: Unable to update common entries of recording "
2021 "request: %s (%d)", __FUNCTION__, mCameraId,
2022 strerror(-res), res);
2023 return res;
2024 }
2025
2026 return OK;
2027}
2028
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002029status_t Camera2Client::updateRecordingStream(const Parameters &params) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002030 status_t res;
2031
2032 if (mRecordingConsumer == 0) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002033 // Create CPU buffer queue endpoint. We need one more buffer here so that we can
2034 // always acquire and free a buffer when the heap is full; otherwise the consumer
2035 // will have buffers in flight we'll never clear out.
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07002036 mRecordingConsumer = new BufferItemConsumer(
2037 GRALLOC_USAGE_HW_VIDEO_ENCODER,
2038 mRecordingHeapCount + 1,
2039 true);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002040 mRecordingConsumer->setFrameAvailableListener(new RecordingWaiter(this));
2041 mRecordingConsumer->setName(String8("Camera2Client::RecordingConsumer"));
2042 mRecordingWindow = new SurfaceTextureClient(
2043 mRecordingConsumer->getProducerInterface());
2044 // Allocate memory later, since we don't know buffer size until receipt
2045 }
2046
2047 if (mRecordingStreamId != NO_STREAM) {
2048 // Check if stream parameters have to change
2049 uint32_t currentWidth, currentHeight;
2050 res = mDevice->getStreamInfo(mRecordingStreamId,
2051 &currentWidth, &currentHeight, 0);
2052 if (res != OK) {
2053 ALOGE("%s: Camera %d: Error querying recording output stream info: "
2054 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2055 return res;
2056 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002057 if (currentWidth != (uint32_t)params.videoWidth ||
2058 currentHeight != (uint32_t)params.videoHeight) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002059 // TODO: Should wait to be sure previous recording has finished
2060 res = mDevice->deleteStream(mRecordingStreamId);
2061 if (res != OK) {
2062 ALOGE("%s: Camera %d: Unable to delete old output stream "
2063 "for recording: %s (%d)", __FUNCTION__, mCameraId,
2064 strerror(-res), res);
2065 return res;
2066 }
2067 mRecordingStreamId = NO_STREAM;
2068 }
2069 }
2070
2071 if (mRecordingStreamId == NO_STREAM) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002072 mRecordingFrameCount = 0;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002073 res = mDevice->createStream(mRecordingWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002074 params.videoWidth, params.videoHeight,
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002075 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0, &mRecordingStreamId);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002076 if (res != OK) {
2077 ALOGE("%s: Camera %d: Can't create output stream for recording: "
2078 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2079 return res;
2080 }
2081 }
2082
2083 return OK;
2084}
2085
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002086status_t Camera2Client::updateRequestCommon(CameraMetadata *request,
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07002087 const Parameters &params) const {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002088 ATRACE_CALL();
2089 status_t res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002090 res = request->update(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
2091 params.previewFpsRange, 2);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002092 if (res != OK) return res;
2093
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002094 uint8_t wbMode = params.autoWhiteBalanceLock ?
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002095 (uint8_t)ANDROID_CONTROL_AWB_LOCKED : params.wbMode;
2096 res = request->update(ANDROID_CONTROL_AWB_MODE,
2097 &wbMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002098 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002099 res = request->update(ANDROID_CONTROL_EFFECT_MODE,
2100 &params.effectMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002101 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002102 res = request->update(ANDROID_CONTROL_AE_ANTIBANDING_MODE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002103 &params.antibandingMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002104 if (res != OK) return res;
2105
2106 uint8_t controlMode =
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002107 (params.sceneMode == ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED) ?
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002108 ANDROID_CONTROL_AUTO : ANDROID_CONTROL_USE_SCENE_MODE;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002109 res = request->update(ANDROID_CONTROL_MODE,
2110 &controlMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002111 if (res != OK) return res;
2112 if (controlMode == ANDROID_CONTROL_USE_SCENE_MODE) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002113 res = request->update(ANDROID_CONTROL_SCENE_MODE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002114 &params.sceneMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002115 if (res != OK) return res;
2116 }
2117
2118 uint8_t flashMode = ANDROID_FLASH_OFF;
2119 uint8_t aeMode;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002120 switch (params.flashMode) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002121 case Parameters::FLASH_MODE_OFF:
2122 aeMode = ANDROID_CONTROL_AE_ON; break;
2123 case Parameters::FLASH_MODE_AUTO:
2124 aeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH; break;
2125 case Parameters::FLASH_MODE_ON:
2126 aeMode = ANDROID_CONTROL_AE_ON_ALWAYS_FLASH; break;
2127 case Parameters::FLASH_MODE_TORCH:
2128 aeMode = ANDROID_CONTROL_AE_ON;
2129 flashMode = ANDROID_FLASH_TORCH;
2130 break;
2131 case Parameters::FLASH_MODE_RED_EYE:
2132 aeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE; break;
2133 default:
2134 ALOGE("%s: Camera %d: Unknown flash mode %d", __FUNCTION__,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002135 mCameraId, params.flashMode);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002136 return BAD_VALUE;
2137 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002138 if (params.autoExposureLock) aeMode = ANDROID_CONTROL_AE_LOCKED;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002139
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002140 res = request->update(ANDROID_FLASH_MODE,
2141 &flashMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002142 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002143 res = request->update(ANDROID_CONTROL_AE_MODE,
2144 &aeMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002145 if (res != OK) return res;
2146
2147 float focusDistance = 0; // infinity focus in diopters
2148 uint8_t focusMode;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002149 switch (params.focusMode) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002150 case Parameters::FOCUS_MODE_AUTO:
2151 case Parameters::FOCUS_MODE_MACRO:
2152 case Parameters::FOCUS_MODE_CONTINUOUS_VIDEO:
2153 case Parameters::FOCUS_MODE_CONTINUOUS_PICTURE:
2154 case Parameters::FOCUS_MODE_EDOF:
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002155 focusMode = params.focusMode;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002156 break;
2157 case Parameters::FOCUS_MODE_INFINITY:
2158 case Parameters::FOCUS_MODE_FIXED:
2159 focusMode = ANDROID_CONTROL_AF_OFF;
2160 break;
2161 default:
2162 ALOGE("%s: Camera %d: Unknown focus mode %d", __FUNCTION__,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002163 mCameraId, params.focusMode);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002164 return BAD_VALUE;
2165 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002166 res = request->update(ANDROID_LENS_FOCUS_DISTANCE,
2167 &focusDistance, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002168 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002169 res = request->update(ANDROID_CONTROL_AF_MODE,
2170 &focusMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002171 if (res != OK) return res;
2172
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002173 size_t focusingAreasSize = params.focusingAreas.size() * 5;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002174 int32_t *focusingAreas = new int32_t[focusingAreasSize];
2175 for (size_t i = 0; i < focusingAreasSize; i += 5) {
Eino-Ville Talvalaf17b6cf2012-08-25 17:12:18 -07002176 if (params.focusingAreas[i].weight != 0) {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07002177 focusingAreas[i + 0] =
2178 params.normalizedXToArray(params.focusingAreas[i].left);
2179 focusingAreas[i + 1] =
2180 params.normalizedYToArray(params.focusingAreas[i].top);
2181 focusingAreas[i + 2] =
2182 params.normalizedXToArray(params.focusingAreas[i].right);
2183 focusingAreas[i + 3] =
2184 params.normalizedYToArray(params.focusingAreas[i].bottom);
Eino-Ville Talvalaf17b6cf2012-08-25 17:12:18 -07002185 } else {
2186 focusingAreas[i + 0] = 0;
2187 focusingAreas[i + 1] = 0;
2188 focusingAreas[i + 2] = 0;
2189 focusingAreas[i + 3] = 0;
2190 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002191 focusingAreas[i + 4] = params.focusingAreas[i].weight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002192 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002193 res = request->update(ANDROID_CONTROL_AF_REGIONS,
2194 focusingAreas,focusingAreasSize);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002195 if (res != OK) return res;
2196 delete[] focusingAreas;
2197
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002198 res = request->update(ANDROID_CONTROL_AE_EXP_COMPENSATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002199 &params.exposureCompensation, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002200 if (res != OK) return res;
2201
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002202 size_t meteringAreasSize = params.meteringAreas.size() * 5;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002203 int32_t *meteringAreas = new int32_t[meteringAreasSize];
2204 for (size_t i = 0; i < meteringAreasSize; i += 5) {
Eino-Ville Talvalaf17b6cf2012-08-25 17:12:18 -07002205 if (params.meteringAreas[i].weight != 0) {
2206 meteringAreas[i + 0] =
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07002207 params.normalizedXToArray(params.meteringAreas[i].left);
Eino-Ville Talvalaf17b6cf2012-08-25 17:12:18 -07002208 meteringAreas[i + 1] =
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07002209 params.normalizedYToArray(params.meteringAreas[i].top);
Eino-Ville Talvalaf17b6cf2012-08-25 17:12:18 -07002210 meteringAreas[i + 2] =
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07002211 params.normalizedXToArray(params.meteringAreas[i].right);
Eino-Ville Talvalaf17b6cf2012-08-25 17:12:18 -07002212 meteringAreas[i + 3] =
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07002213 params.normalizedYToArray(params.meteringAreas[i].bottom);
Eino-Ville Talvalaf17b6cf2012-08-25 17:12:18 -07002214 } else {
2215 meteringAreas[i + 0] = 0;
2216 meteringAreas[i + 1] = 0;
2217 meteringAreas[i + 2] = 0;
2218 meteringAreas[i + 3] = 0;
2219 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002220 meteringAreas[i + 4] = params.meteringAreas[i].weight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002221 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002222 res = request->update(ANDROID_CONTROL_AE_REGIONS,
2223 meteringAreas, meteringAreasSize);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002224 if (res != OK) return res;
2225
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002226 res = request->update(ANDROID_CONTROL_AWB_REGIONS,
2227 meteringAreas, meteringAreasSize);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002228 if (res != OK) return res;
2229 delete[] meteringAreas;
2230
2231 // Need to convert zoom index into a crop rectangle. The rectangle is
2232 // chosen to maximize its area on the sensor
2233
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002234 camera_metadata_ro_entry_t maxDigitalZoom =
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07002235 mParameters.staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002236 float zoomIncrement = (maxDigitalZoom.data.f[0] - 1) /
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07002237 (params.NUM_ZOOM_STEPS-1);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002238 float zoomRatio = 1 + zoomIncrement * params.zoom;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002239
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002240 float zoomLeft, zoomTop, zoomWidth, zoomHeight;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002241 if (params.previewWidth >= params.previewHeight) {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07002242 zoomWidth = params.fastInfo.arrayWidth / zoomRatio;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002243 zoomHeight = zoomWidth *
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002244 params.previewHeight / params.previewWidth;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002245 } else {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07002246 zoomHeight = params.fastInfo.arrayHeight / zoomRatio;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002247 zoomWidth = zoomHeight *
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002248 params.previewWidth / params.previewHeight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002249 }
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07002250 zoomLeft = (params.fastInfo.arrayWidth - zoomWidth) / 2;
2251 zoomTop = (params.fastInfo.arrayHeight - zoomHeight) / 2;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002252
2253 int32_t cropRegion[3] = { zoomLeft, zoomTop, zoomWidth };
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002254 res = request->update(ANDROID_SCALER_CROP_REGION,
2255 cropRegion, 3);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002256 if (res != OK) return res;
2257
2258 // TODO: Decide how to map recordingHint, or whether just to ignore it
2259
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002260 uint8_t vstabMode = params.videoStabilization ?
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002261 ANDROID_CONTROL_VIDEO_STABILIZATION_ON :
2262 ANDROID_CONTROL_VIDEO_STABILIZATION_OFF;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002263 res = request->update(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002264 &vstabMode, 1);
2265 if (res != OK) return res;
2266
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002267 uint8_t faceDetectMode = params.enableFaceDetect ?
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07002268 params.fastInfo.bestFaceDetectMode :
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002269 (uint8_t)ANDROID_STATS_FACE_DETECTION_OFF;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002270 res = request->update(ANDROID_STATS_FACE_DETECT_MODE,
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002271 &faceDetectMode, 1);
2272 if (res != OK) return res;
2273
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002274 return OK;
2275}
2276
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002277size_t Camera2Client::calculateBufferSize(int width, int height,
2278 int format, int stride) {
2279 switch (format) {
2280 case HAL_PIXEL_FORMAT_YCbCr_422_SP: // NV16
2281 return width * height * 2;
2282 case HAL_PIXEL_FORMAT_YCrCb_420_SP: // NV21
2283 return width * height * 3 / 2;
2284 case HAL_PIXEL_FORMAT_YCbCr_422_I: // YUY2
2285 return width * height * 2;
2286 case HAL_PIXEL_FORMAT_YV12: { // YV12
2287 size_t ySize = stride * height;
Eino-Ville Talvalaf17b6cf2012-08-25 17:12:18 -07002288 size_t uvStride = (stride / 2 + 0xF) & ~0xF;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002289 size_t uvSize = uvStride * height / 2;
2290 return ySize + uvSize * 2;
2291 }
2292 case HAL_PIXEL_FORMAT_RGB_565:
2293 return width * height * 2;
2294 case HAL_PIXEL_FORMAT_RGBA_8888:
2295 return width * height * 4;
2296 case HAL_PIXEL_FORMAT_RAW_SENSOR:
2297 return width * height * 2;
2298 default:
2299 ALOGE("%s: Unknown preview format: %x",
2300 __FUNCTION__, format);
2301 return 0;
2302 }
2303}
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002304
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07002305} // namespace android