blob: 9b6401b7184436de1c402084423e40ea0fb67235 [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 Talvala2e19c3c2012-08-26 09:29:28 -070055 mParameters(cameraId, cameraFacing),
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -070056 mPreviewStreamId(NO_STREAM),
Eino-Ville Talvala228a5382012-08-13 12:16:06 -070057 mCallbackStreamId(NO_STREAM),
58 mCallbackHeapId(0),
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -070059 mCaptureStreamId(NO_STREAM),
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -070060 mRecordingStreamId(NO_STREAM),
James Dong983cf232012-08-01 16:39:55 -070061 mRecordingHeapCount(kDefaultRecordingHeapCount)
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070062{
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070063 ATRACE_CALL();
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -070064 ALOGV("%s: Created client for camera %d", __FUNCTION__, cameraId);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070065
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070066 mDevice = new Camera2Device(cameraId);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -070067
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
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -070087 mFrameProcessor = new FrameProcessor(this);
88 String8 frameThreadName = String8::format("Camera2Client[%d]::FrameProcessor",
89 mCameraId);
90 mFrameProcessor->run(frameThreadName.string());
91
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070092 res = mDevice->initialize(module);
93 if (res != OK) {
94 ALOGE("%s: Camera %d: unable to initialize device: %s (%d)",
95 __FUNCTION__, mCameraId, strerror(-res), res);
96 return NO_INIT;
97 }
98
Eino-Ville Talvala174181e2012-08-03 13:53:39 -070099 res = mDevice->setNotifyCallback(this);
100
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700101 SharedParameters::Lock l(mParameters);
102
103 res = l.mParameters.initialize(&(mDevice->info()));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700104 if (res != OK) {
105 ALOGE("%s: Camera %d: unable to build defaults: %s (%d)",
106 __FUNCTION__, mCameraId, strerror(-res), res);
107 return NO_INIT;
108 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -0700109
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700110 if (gLogLevel >= 1) {
111 ALOGD("%s: Default parameters converted from camera %d:", __FUNCTION__,
112 mCameraId);
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700113 ALOGD("%s", l.mParameters.paramsFlattened.string());
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700114 }
115
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700116 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700117}
118
119Camera2Client::~Camera2Client() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700120 ATRACE_CALL();
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -0700121 ALOGV("%s: Camera %d: Shutting down client.", __FUNCTION__, mCameraId);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700122
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700123 mDestructionStarted = true;
124
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700125 // Rewrite mClientPid to allow shutdown by CameraService
126 mClientPid = getCallingPid();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700127 disconnect();
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -0700128
129 mFrameProcessor->requestExit();
130 ALOGV("%s: Camera %d: Shutdown complete", __FUNCTION__, mCameraId);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700131}
132
133status_t Camera2Client::dump(int fd, const Vector<String16>& args) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700134 String8 result;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700135 result.appendFormat("Client2[%d] (%p) PID: %d, dump:\n",
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700136 mCameraId,
137 getCameraClient()->asBinder().get(),
138 mClientPid);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700139 result.append(" State: ");
140#define CASE_APPEND_ENUM(x) case x: result.append(#x "\n"); break;
141
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700142 const Parameters& p = mParameters.unsafeAccess();
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700143
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700144 result.append(Parameters::getStateName(p.state));
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700145
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700146 result.append("\n Current parameters:\n");
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700147 result.appendFormat(" Preview size: %d x %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700148 p.previewWidth, p.previewHeight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700149 result.appendFormat(" Preview FPS range: %d - %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700150 p.previewFpsRange[0], p.previewFpsRange[1]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700151 result.appendFormat(" Preview HAL pixel format: 0x%x\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700152 p.previewFormat);
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700153 result.appendFormat(" Preview transform: %x\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700154 p.previewTransform);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700155 result.appendFormat(" Picture size: %d x %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700156 p.pictureWidth, p.pictureHeight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700157 result.appendFormat(" Jpeg thumbnail size: %d x %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700158 p.jpegThumbSize[0], p.jpegThumbSize[1]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700159 result.appendFormat(" Jpeg quality: %d, thumbnail quality: %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700160 p.jpegQuality, p.jpegThumbQuality);
161 result.appendFormat(" Jpeg rotation: %d\n", p.jpegRotation);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700162 result.appendFormat(" GPS tags %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700163 p.gpsEnabled ? "enabled" : "disabled");
164 if (p.gpsEnabled) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700165 result.appendFormat(" GPS lat x long x alt: %f x %f x %f\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700166 p.gpsCoordinates[0], p.gpsCoordinates[1],
167 p.gpsCoordinates[2]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700168 result.appendFormat(" GPS timestamp: %lld\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700169 p.gpsTimestamp);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700170 result.appendFormat(" GPS processing method: %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700171 p.gpsProcessingMethod.string());
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700172 }
173
174 result.append(" White balance mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700175 switch (p.wbMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700176 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_AUTO)
177 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_INCANDESCENT)
178 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_FLUORESCENT)
179 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_WARM_FLUORESCENT)
180 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_DAYLIGHT)
181 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT)
182 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_TWILIGHT)
183 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_SHADE)
184 default: result.append("UNKNOWN\n");
185 }
186
187 result.append(" Effect mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700188 switch (p.effectMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700189 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_OFF)
190 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_MONO)
191 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_NEGATIVE)
192 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_SOLARIZE)
193 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_SEPIA)
194 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_POSTERIZE)
195 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_WHITEBOARD)
196 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_BLACKBOARD)
197 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_AQUA)
198 default: result.append("UNKNOWN\n");
199 }
200
201 result.append(" Antibanding mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700202 switch (p.antibandingMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700203 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_AUTO)
204 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_OFF)
205 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_50HZ)
206 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_60HZ)
207 default: result.append("UNKNOWN\n");
208 }
209
210 result.append(" Scene mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700211 switch (p.sceneMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700212 case ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED:
213 result.append("AUTO\n"); break;
214 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_ACTION)
215 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_PORTRAIT)
216 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_LANDSCAPE)
217 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_NIGHT)
218 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT)
219 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_THEATRE)
220 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_BEACH)
221 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SNOW)
222 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SUNSET)
223 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO)
224 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_FIREWORKS)
225 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SPORTS)
226 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_PARTY)
227 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT)
228 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_BARCODE)
229 default: result.append("UNKNOWN\n");
230 }
231
232 result.append(" Flash mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700233 switch (p.flashMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700234 CASE_APPEND_ENUM(Parameters::FLASH_MODE_OFF)
235 CASE_APPEND_ENUM(Parameters::FLASH_MODE_AUTO)
236 CASE_APPEND_ENUM(Parameters::FLASH_MODE_ON)
237 CASE_APPEND_ENUM(Parameters::FLASH_MODE_TORCH)
238 CASE_APPEND_ENUM(Parameters::FLASH_MODE_RED_EYE)
239 CASE_APPEND_ENUM(Parameters::FLASH_MODE_INVALID)
240 default: result.append("UNKNOWN\n");
241 }
242
243 result.append(" Focus mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700244 switch (p.focusMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700245 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_AUTO)
246 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_MACRO)
247 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_CONTINUOUS_VIDEO)
248 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_CONTINUOUS_PICTURE)
249 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_EDOF)
250 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_INFINITY)
251 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_FIXED)
252 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_INVALID)
253 default: result.append("UNKNOWN\n");
254 }
255
256 result.append(" Focusing areas:\n");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700257 for (size_t i = 0; i < p.focusingAreas.size(); i++) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700258 result.appendFormat(" [ (%d, %d, %d, %d), weight %d ]\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700259 p.focusingAreas[i].left,
260 p.focusingAreas[i].top,
261 p.focusingAreas[i].right,
262 p.focusingAreas[i].bottom,
263 p.focusingAreas[i].weight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700264 }
265
266 result.appendFormat(" Exposure compensation index: %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700267 p.exposureCompensation);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700268
269 result.appendFormat(" AE lock %s, AWB lock %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700270 p.autoExposureLock ? "enabled" : "disabled",
271 p.autoWhiteBalanceLock ? "enabled" : "disabled" );
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700272
273 result.appendFormat(" Metering areas:\n");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700274 for (size_t i = 0; i < p.meteringAreas.size(); i++) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700275 result.appendFormat(" [ (%d, %d, %d, %d), weight %d ]\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700276 p.meteringAreas[i].left,
277 p.meteringAreas[i].top,
278 p.meteringAreas[i].right,
279 p.meteringAreas[i].bottom,
280 p.meteringAreas[i].weight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700281 }
282
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700283 result.appendFormat(" Zoom index: %d\n", p.zoom);
284 result.appendFormat(" Video size: %d x %d\n", p.videoWidth,
285 p.videoHeight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700286
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700287 result.appendFormat(" Recording hint is %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700288 p.recordingHint ? "set" : "not set");
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700289
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700290 result.appendFormat(" Video stabilization is %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700291 p.videoStabilization ? "enabled" : "disabled");
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700292
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700293 result.append(" Current streams:\n");
294 result.appendFormat(" Preview stream ID: %d\n", mPreviewStreamId);
295 result.appendFormat(" Capture stream ID: %d\n", mCaptureStreamId);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700296 result.appendFormat(" Recording stream ID: %d\n", mRecordingStreamId);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700297
298 result.append(" Current requests:\n");
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700299 if (mPreviewRequest.entryCount() != 0) {
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700300 result.append(" Preview request:\n");
301 write(fd, result.string(), result.size());
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700302 mPreviewRequest.dump(fd, 2, 6);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700303 } else {
304 result.append(" Preview request: undefined\n");
305 write(fd, result.string(), result.size());
306 }
307
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700308 if (mCaptureRequest.entryCount() != 0) {
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700309 result = " Capture request:\n";
310 write(fd, result.string(), result.size());
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700311 mCaptureRequest.dump(fd, 2, 6);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700312 } else {
313 result = " Capture request: undefined\n";
314 write(fd, result.string(), result.size());
315 }
316
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700317 if (mRecordingRequest.entryCount() != 0) {
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700318 result = " Recording request:\n";
319 write(fd, result.string(), result.size());
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700320 mRecordingRequest.dump(fd, 2, 6);
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700321 } else {
322 result = " Recording request: undefined\n";
323 write(fd, result.string(), result.size());
324 }
325
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -0700326 mFrameProcessor->dump(fd, args);
327
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700328 result = " Device dump:\n";
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700329 write(fd, result.string(), result.size());
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700330
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700331 status_t res = mDevice->dump(fd, args);
332 if (res != OK) {
333 result = String8::format(" Error dumping device: %s (%d)",
334 strerror(-res), res);
335 write(fd, result.string(), result.size());
336 }
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700337
338#undef CASE_APPEND_ENUM
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700339 return NO_ERROR;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700340}
341
342// ICamera interface
343
344void Camera2Client::disconnect() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700345 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700346 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700347 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700348 status_t res;
349 if ( (res = checkPid(__FUNCTION__) ) != OK) return;
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700350
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700351 if (mDevice == 0) return;
352
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700353 stopPreviewL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700354
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700355 if (mPreviewStreamId != NO_STREAM) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700356 mDevice->deleteStream(mPreviewStreamId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700357 mPreviewStreamId = NO_STREAM;
358 }
359
360 if (mCaptureStreamId != NO_STREAM) {
361 mDevice->deleteStream(mCaptureStreamId);
362 mCaptureStreamId = NO_STREAM;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700363 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700364
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -0700365 if (mRecordingStreamId != NO_STREAM) {
366 mDevice->deleteStream(mRecordingStreamId);
367 mRecordingStreamId = NO_STREAM;
368 }
369
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700370 if (mCallbackStreamId != NO_STREAM) {
371 mDevice->deleteStream(mCallbackStreamId);
372 mCallbackStreamId = NO_STREAM;
373 }
374
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700375 mDevice.clear();
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700376 SharedParameters::Lock l(mParameters);
377 l.mParameters.state = Parameters::DISCONNECTED;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700378
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700379 CameraService::Client::disconnect();
380}
381
382status_t Camera2Client::connect(const sp<ICameraClient>& client) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700383 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700384 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700385 Mutex::Autolock icl(mICameraLock);
386
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700387 if (mClientPid != 0 && getCallingPid() != mClientPid) {
388 ALOGE("%s: Camera %d: Connection attempt from pid %d; "
389 "current locked to pid %d", __FUNCTION__,
390 mCameraId, getCallingPid(), mClientPid);
391 return BAD_VALUE;
392 }
393
394 mClientPid = getCallingPid();
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700395
396 Mutex::Autolock iccl(mICameraClientLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700397 mCameraClient = client;
398
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700399 SharedParameters::Lock l(mParameters);
400 l.mParameters.state = Parameters::STOPPED;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700401
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700402 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700403}
404
405status_t Camera2Client::lock() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700406 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700407 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700408 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700409 ALOGV("%s: Camera %d: Lock call from pid %d; current client pid %d",
410 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700411
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700412 if (mClientPid == 0) {
413 mClientPid = getCallingPid();
414 return OK;
415 }
416
417 if (mClientPid != getCallingPid()) {
418 ALOGE("%s: Camera %d: Lock call from pid %d; currently locked to pid %d",
419 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
420 return EBUSY;
421 }
422
423 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700424}
425
426status_t Camera2Client::unlock() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700427 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700428 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700429 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700430 ALOGV("%s: Camera %d: Unlock call from pid %d; current client pid %d",
431 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700432
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700433 // TODO: Check for uninterruptable conditions
434
435 if (mClientPid == getCallingPid()) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700436 Mutex::Autolock iccl(mICameraClientLock);
437
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700438 mClientPid = 0;
439 mCameraClient.clear();
440 return OK;
441 }
442
443 ALOGE("%s: Camera %d: Unlock call from pid %d; currently locked to pid %d",
444 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
445 return EBUSY;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700446}
447
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700448status_t Camera2Client::setPreviewDisplay(
449 const sp<Surface>& surface) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700450 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700451 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700452 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700453 status_t res;
454 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700455
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700456 sp<IBinder> binder;
457 sp<ANativeWindow> window;
458 if (surface != 0) {
459 binder = surface->asBinder();
460 window = surface;
461 }
462
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700463 return setPreviewWindowL(binder,window);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700464}
465
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700466status_t Camera2Client::setPreviewTexture(
467 const sp<ISurfaceTexture>& surfaceTexture) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700468 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700469 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700470 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700471 status_t res;
472 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700473
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700474 sp<IBinder> binder;
475 sp<ANativeWindow> window;
476 if (surfaceTexture != 0) {
477 binder = surfaceTexture->asBinder();
478 window = new SurfaceTextureClient(surfaceTexture);
479 }
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700480 return setPreviewWindowL(binder, window);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700481}
482
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700483status_t Camera2Client::setPreviewWindowL(const sp<IBinder>& binder,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700484 sp<ANativeWindow> window) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700485 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700486 status_t res;
487
488 if (binder == mPreviewSurface) {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700489 ALOGV("%s: Camera %d: New window is same as old window",
490 __FUNCTION__, mCameraId);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700491 return NO_ERROR;
492 }
493
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700494 SharedParameters::Lock l(mParameters);
495 switch (l.mParameters.state) {
496 case Parameters::DISCONNECTED:
497 case Parameters::RECORD:
498 case Parameters::STILL_CAPTURE:
499 case Parameters::VIDEO_SNAPSHOT:
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700500 ALOGE("%s: Camera %d: Cannot set preview display while in state %s",
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700501 __FUNCTION__, mCameraId,
502 Parameters::getStateName(l.mParameters.state));
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700503 return INVALID_OPERATION;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700504 case Parameters::STOPPED:
505 case Parameters::WAITING_FOR_PREVIEW_WINDOW:
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700506 // OK
507 break;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700508 case Parameters::PREVIEW:
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700509 // Already running preview - need to stop and create a new stream
510 // TODO: Optimize this so that we don't wait for old stream to drain
511 // before spinning up new stream
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700512 mDevice->clearStreamingRequest();
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700513 l.mParameters.state = Parameters::WAITING_FOR_PREVIEW_WINDOW;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700514 break;
515 }
516
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700517 if (mPreviewStreamId != NO_STREAM) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700518 res = mDevice->waitUntilDrained();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700519 if (res != OK) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700520 ALOGE("%s: Error waiting for preview to drain: %s (%d)",
521 __FUNCTION__, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700522 return res;
523 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700524 res = mDevice->deleteStream(mPreviewStreamId);
525 if (res != OK) {
526 ALOGE("%s: Unable to delete old preview stream: %s (%d)",
527 __FUNCTION__, strerror(-res), res);
528 return res;
529 }
530 mPreviewStreamId = NO_STREAM;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700531 }
532
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700533 mPreviewSurface = binder;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700534 mPreviewWindow = window;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700535
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700536 if (l.mParameters.state == Parameters::WAITING_FOR_PREVIEW_WINDOW) {
537 return startPreviewL(l.mParameters, false);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700538 }
539
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700540 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700541}
542
543void Camera2Client::setPreviewCallbackFlag(int flag) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700544 ATRACE_CALL();
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700545 ALOGV("%s: Camera %d: Flag 0x%x", __FUNCTION__, mCameraId, flag);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700546 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700547 status_t res;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700548 if ( checkPid(__FUNCTION__) != OK) return;
549
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700550 SharedParameters::Lock l(mParameters);
551 setPreviewCallbackFlagL(l.mParameters, flag);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700552}
553
554void Camera2Client::setPreviewCallbackFlagL(Parameters &params, int flag) {
555 status_t res = OK;
556 if (flag & CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) {
557 ALOGV("%s: setting oneshot", __FUNCTION__);
558 params.previewCallbackOneShot = true;
559 }
560 if (params.previewCallbackFlags != (uint32_t)flag) {
561 params.previewCallbackFlags = flag;
562 switch(params.state) {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700563 case Parameters::PREVIEW:
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700564 res = startPreviewL(params, true);
565 break;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700566 case Parameters::RECORD:
567 case Parameters::VIDEO_SNAPSHOT:
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700568 res = startRecordingL(params, true);
569 break;
570 default:
571 break;
572 }
573 if (res != OK) {
574 ALOGE("%s: Camera %d: Unable to refresh request in state %s",
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700575 __FUNCTION__, mCameraId,
576 Parameters::getStateName(params.state));
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700577 }
578 }
579
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700580}
581
582status_t Camera2Client::startPreview() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700583 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700584 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700585 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700586 status_t res;
587 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700588 SharedParameters::Lock l(mParameters);
589 return startPreviewL(l.mParameters, false);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700590}
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700591
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700592status_t Camera2Client::startPreviewL(Parameters &params, bool restart) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700593 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700594 status_t res;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700595 if (params.state >= Parameters::PREVIEW && !restart) {
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700596 ALOGE("%s: Can't start preview in state %s",
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700597 __FUNCTION__,
598 Parameters::getStateName(params.state));
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700599 return INVALID_OPERATION;
600 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700601
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700602 if (mPreviewWindow == 0) {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700603 params.state = Parameters::WAITING_FOR_PREVIEW_WINDOW;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700604 return OK;
605 }
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700606 params.state = Parameters::STOPPED;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700607
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700608 res = updatePreviewStream(params);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700609 if (res != OK) {
610 ALOGE("%s: Camera %d: Unable to update preview stream: %s (%d)",
611 __FUNCTION__, mCameraId, strerror(-res), res);
612 return res;
613 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700614 bool callbacksEnabled = params.previewCallbackFlags &
615 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK;
616 if (callbacksEnabled) {
617 res = updateCallbackStream(params);
618 if (res != OK) {
619 ALOGE("%s: Camera %d: Unable to update callback stream: %s (%d)",
620 __FUNCTION__, mCameraId, strerror(-res), res);
621 return res;
622 }
623 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700624
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700625 if (mPreviewRequest.entryCount() == 0) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700626 res = updatePreviewRequest(params);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700627 if (res != OK) {
628 ALOGE("%s: Camera %d: Unable to create preview request: %s (%d)",
629 __FUNCTION__, mCameraId, strerror(-res), res);
630 return res;
631 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700632 }
633
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700634 if (callbacksEnabled) {
635 uint8_t outputStreams[2] =
636 { mPreviewStreamId, mCallbackStreamId };
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700637 res = mPreviewRequest.update(
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700638 ANDROID_REQUEST_OUTPUT_STREAMS,
639 outputStreams, 2);
640 } else {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700641 uint8_t outputStreams[1] = { mPreviewStreamId };
642 res = mPreviewRequest.update(
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700643 ANDROID_REQUEST_OUTPUT_STREAMS,
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700644 outputStreams, 1);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700645 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700646 if (res != OK) {
647 ALOGE("%s: Camera %d: Unable to set up preview request: %s (%d)",
648 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700649 return res;
650 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700651 res = mPreviewRequest.sort();
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700652 if (res != OK) {
653 ALOGE("%s: Camera %d: Error sorting preview request: %s (%d)",
654 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700655 return res;
656 }
657
658 res = mDevice->setStreamingRequest(mPreviewRequest);
659 if (res != OK) {
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700660 ALOGE("%s: Camera %d: Unable to set preview request to start preview: "
661 "%s (%d)",
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700662 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700663 return res;
664 }
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700665 params.state = Parameters::PREVIEW;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700666
667 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700668}
669
670void Camera2Client::stopPreview() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700671 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700672 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700673 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700674 status_t res;
675 if ( (res = checkPid(__FUNCTION__) ) != OK) return;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700676 stopPreviewL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700677}
678
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700679void Camera2Client::stopPreviewL() {
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700680 ATRACE_CALL();
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700681 Parameters::State state;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700682 {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700683 SharedParameters::Lock l(mParameters);
684 state = l.mParameters.state;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700685 }
686
687 switch (state) {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700688 case Parameters::DISCONNECTED:
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700689 ALOGE("%s: Camera %d: Call before initialized",
690 __FUNCTION__, mCameraId);
691 break;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700692 case Parameters::STOPPED:
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700693 break;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700694 case Parameters::STILL_CAPTURE:
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700695 ALOGE("%s: Camera %d: Cannot stop preview during still capture.",
696 __FUNCTION__, mCameraId);
697 break;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700698 case Parameters::RECORD:
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700699 // no break - identical to preview
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700700 case Parameters::PREVIEW:
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700701 mDevice->clearStreamingRequest();
Eino-Ville Talvala22671062012-07-20 18:30:37 -0700702 mDevice->waitUntilDrained();
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700703 // no break
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700704 case Parameters::WAITING_FOR_PREVIEW_WINDOW: {
705 SharedParameters::Lock l(mParameters);
706 l.mParameters.state = Parameters::STOPPED;
707 commandStopFaceDetectionL(l.mParameters);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700708 break;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700709 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700710 default:
711 ALOGE("%s: Camera %d: Unknown state %d", __FUNCTION__, mCameraId,
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700712 state);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700713 }
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700714}
715
716bool Camera2Client::previewEnabled() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700717 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700718 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700719 status_t res;
720 if ( (res = checkPid(__FUNCTION__) ) != OK) return false;
721
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700722 SharedParameters::Lock l(mParameters);
723 return l.mParameters.state == Parameters::PREVIEW;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700724}
725
726status_t Camera2Client::storeMetaDataInBuffers(bool enabled) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700727 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700728 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700729 status_t res;
730 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
731
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700732 SharedParameters::Lock l(mParameters);
733 switch (l.mParameters.state) {
734 case Parameters::RECORD:
735 case Parameters::VIDEO_SNAPSHOT:
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700736 ALOGE("%s: Camera %d: Can't be called in state %s",
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700737 __FUNCTION__, mCameraId,
738 Parameters::getStateName(l.mParameters.state));
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700739 return INVALID_OPERATION;
740 default:
741 // OK
742 break;
743 }
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700744
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700745 l.mParameters.storeMetadataInBuffers = enabled;
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700746
747 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700748}
749
750status_t Camera2Client::startRecording() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700751 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700752 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700753 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700754 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700755 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700756 SharedParameters::Lock l(mParameters);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700757
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700758 return startRecordingL(l.mParameters, false);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700759}
760
761status_t Camera2Client::startRecordingL(Parameters &params, bool restart) {
762 status_t res;
763 switch (params.state) {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700764 case Parameters::STOPPED:
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700765 res = startPreviewL(params, false);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700766 if (res != OK) return res;
767 break;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700768 case Parameters::PREVIEW:
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700769 // Ready to go
770 break;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700771 case Parameters::RECORD:
772 case Parameters::VIDEO_SNAPSHOT:
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700773 // OK to call this when recording is already on, just skip unless
774 // we're looking to restart
775 if (!restart) return OK;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700776 break;
777 default:
778 ALOGE("%s: Camera %d: Can't start recording in state %s",
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700779 __FUNCTION__, mCameraId,
780 Parameters::getStateName(params.state));
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700781 return INVALID_OPERATION;
782 };
783
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700784 if (!params.storeMetadataInBuffers) {
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700785 ALOGE("%s: Camera %d: Recording only supported in metadata mode, but "
786 "non-metadata recording mode requested!", __FUNCTION__,
787 mCameraId);
788 return INVALID_OPERATION;
789 }
790
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700791 res = updateRecordingStream(params);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700792 if (res != OK) {
793 ALOGE("%s: Camera %d: Unable to update recording stream: %s (%d)",
794 __FUNCTION__, mCameraId, strerror(-res), res);
795 return res;
796 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700797 bool callbacksEnabled = params.previewCallbackFlags &
798 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK;
799 if (callbacksEnabled) {
800 res = updateCallbackStream(params);
801 if (res != OK) {
802 ALOGE("%s: Camera %d: Unable to update callback stream: %s (%d)",
803 __FUNCTION__, mCameraId, strerror(-res), res);
804 return res;
805 }
806 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700807
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700808 if (mRecordingRequest.entryCount() == 0) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700809 res = updateRecordingRequest(params);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700810 if (res != OK) {
811 ALOGE("%s: Camera %d: Unable to create recording request: %s (%d)",
812 __FUNCTION__, mCameraId, strerror(-res), res);
813 return res;
814 }
815 }
816
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700817 if (callbacksEnabled) {
818 uint8_t outputStreams[3] =
819 { mPreviewStreamId, mRecordingStreamId, mCallbackStreamId };
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700820 res = mRecordingRequest.update(
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700821 ANDROID_REQUEST_OUTPUT_STREAMS,
822 outputStreams, 3);
823 } else {
824 uint8_t outputStreams[2] = { mPreviewStreamId, mRecordingStreamId };
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700825 res = mRecordingRequest.update(
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700826 ANDROID_REQUEST_OUTPUT_STREAMS,
827 outputStreams, 2);
828 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700829 if (res != OK) {
830 ALOGE("%s: Camera %d: Unable to set up recording request: %s (%d)",
831 __FUNCTION__, mCameraId, strerror(-res), res);
832 return res;
833 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700834 res = mRecordingRequest.sort();
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700835 if (res != OK) {
836 ALOGE("%s: Camera %d: Error sorting recording request: %s (%d)",
837 __FUNCTION__, mCameraId, strerror(-res), res);
838 return res;
839 }
840
841 res = mDevice->setStreamingRequest(mRecordingRequest);
842 if (res != OK) {
843 ALOGE("%s: Camera %d: Unable to set recording request to start "
844 "recording: %s (%d)", __FUNCTION__, mCameraId,
845 strerror(-res), res);
846 return res;
847 }
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700848 if (params.state < Parameters::RECORD) {
849 params.state = Parameters::RECORD;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700850 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700851
852 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700853}
854
855void Camera2Client::stopRecording() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700856 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700857 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700858 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700859 SharedParameters::Lock l(mParameters);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700860
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700861 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700862 if ( (res = checkPid(__FUNCTION__) ) != OK) return;
863
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700864 switch (l.mParameters.state) {
865 case Parameters::RECORD:
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700866 // OK to stop
867 break;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700868 case Parameters::STOPPED:
869 case Parameters::PREVIEW:
870 case Parameters::STILL_CAPTURE:
871 case Parameters::VIDEO_SNAPSHOT:
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700872 default:
873 ALOGE("%s: Camera %d: Can't stop recording in state %s",
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700874 __FUNCTION__, mCameraId,
875 Parameters::getStateName(l.mParameters.state));
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700876 return;
877 };
878
879 // Back to preview. Since record can only be reached through preview,
880 // all preview stream setup should be up to date.
881 res = mDevice->setStreamingRequest(mPreviewRequest);
882 if (res != OK) {
883 ALOGE("%s: Camera %d: Unable to switch back to preview request: "
884 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
885 return;
886 }
887
888 // TODO: Should recording heap be freed? Can't do it yet since requests
889 // could still be in flight.
890
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700891 l.mParameters.state = Parameters::PREVIEW;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700892}
893
894bool Camera2Client::recordingEnabled() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700895 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700896 Mutex::Autolock icl(mICameraLock);
James Dong8da4cd72012-08-04 19:58:07 -0700897
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700898 if ( checkPid(__FUNCTION__) != OK) return false;
899
James Dong8da4cd72012-08-04 19:58:07 -0700900 return recordingEnabledL();
901}
902
903bool Camera2Client::recordingEnabledL() {
904 ATRACE_CALL();
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700905 SharedParameters::Lock l(mParameters);
James Dong8da4cd72012-08-04 19:58:07 -0700906
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700907 return (l.mParameters.state == Parameters::RECORD
908 || l.mParameters.state == Parameters::VIDEO_SNAPSHOT);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700909}
910
911void Camera2Client::releaseRecordingFrame(const sp<IMemory>& mem) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700912 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700913 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700914 status_t res;
915 if ( checkPid(__FUNCTION__) != OK) return;
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -0700916
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700917 SharedParameters::Lock l(mParameters);
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -0700918
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700919 // Make sure this is for the current heap
920 ssize_t offset;
921 size_t size;
922 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
923 if (heap->getHeapID() != mRecordingHeap->mHeap->getHeapID()) {
924 ALOGW("%s: Camera %d: Mismatched heap ID, ignoring release "
925 "(got %x, expected %x)", __FUNCTION__, mCameraId,
926 heap->getHeapID(), mRecordingHeap->mHeap->getHeapID());
927 return;
928 }
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700929 uint8_t *data = (uint8_t*)heap->getBase() + offset;
930 uint32_t type = *(uint32_t*)data;
931 if (type != kMetadataBufferTypeGrallocSource) {
932 ALOGE("%s: Camera %d: Recording frame type invalid (got %x, expected %x)",
933 __FUNCTION__, mCameraId, type, kMetadataBufferTypeGrallocSource);
934 return;
935 }
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -0700936
937 // Release the buffer back to the recording queue
938
939 buffer_handle_t imgHandle = *(buffer_handle_t*)(data + 4);
940
941 size_t itemIndex;
942 for (itemIndex = 0; itemIndex < mRecordingBuffers.size(); itemIndex++) {
943 const BufferItemConsumer::BufferItem item = mRecordingBuffers[itemIndex];
944 if (item.mBuf != BufferItemConsumer::INVALID_BUFFER_SLOT &&
945 item.mGraphicBuffer->handle == imgHandle) {
946 break;
947 }
948 }
949 if (itemIndex == mRecordingBuffers.size()) {
950 ALOGE("%s: Camera %d: Can't find buffer_handle_t %p in list of "
951 "outstanding buffers", __FUNCTION__, mCameraId, imgHandle);
952 return;
953 }
954
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700955 ALOGV("%s: Camera %d: Freeing buffer_handle_t %p", __FUNCTION__, mCameraId,
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -0700956 imgHandle);
957
958 res = mRecordingConsumer->releaseBuffer(mRecordingBuffers[itemIndex]);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700959 if (res != OK) {
960 ALOGE("%s: Camera %d: Unable to free recording frame (buffer_handle_t: %p):"
961 "%s (%d)",
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -0700962 __FUNCTION__, mCameraId, imgHandle, strerror(-res), res);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700963 return;
964 }
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -0700965 mRecordingBuffers.replaceAt(itemIndex);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700966
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700967 mRecordingHeapFree++;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700968}
969
970status_t Camera2Client::autoFocus() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700971 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700972 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700973 status_t res;
974 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
975
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700976 int triggerId;
977 {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700978 SharedParameters::Lock l(mParameters);
979 l.mParameters.currentAfTriggerId = ++l.mParameters.afTriggerCounter;
980 triggerId = l.mParameters.currentAfTriggerId;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700981 }
982
983 mDevice->triggerAutofocus(triggerId);
984
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700985 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700986}
987
988status_t Camera2Client::cancelAutoFocus() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700989 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700990 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700991 status_t res;
992 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
993
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700994 int triggerId;
995 {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700996 SharedParameters::Lock l(mParameters);
997 triggerId = ++l.mParameters.afTriggerCounter;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700998 }
999
1000 mDevice->triggerCancelAutofocus(triggerId);
1001
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001002 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001003}
1004
1005status_t Camera2Client::takePicture(int msgType) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001006 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001007 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001008 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001009 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001010
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001011 SharedParameters::Lock l(mParameters);
1012 switch (l.mParameters.state) {
1013 case Parameters::DISCONNECTED:
1014 case Parameters::STOPPED:
1015 case Parameters::WAITING_FOR_PREVIEW_WINDOW:
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001016 ALOGE("%s: Camera %d: Cannot take picture without preview enabled",
1017 __FUNCTION__, mCameraId);
1018 return INVALID_OPERATION;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001019 case Parameters::PREVIEW:
1020 case Parameters::RECORD:
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001021 // Good to go for takePicture
1022 break;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001023 case Parameters::STILL_CAPTURE:
1024 case Parameters::VIDEO_SNAPSHOT:
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001025 ALOGE("%s: Camera %d: Already taking a picture",
1026 __FUNCTION__, mCameraId);
1027 return INVALID_OPERATION;
1028 }
1029
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001030 ALOGV("%s: Camera %d: Starting picture capture", __FUNCTION__, mCameraId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001031
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001032 res = updateCaptureStream(l.mParameters);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001033 if (res != OK) {
1034 ALOGE("%s: Camera %d: Can't set up still image stream: %s (%d)",
1035 __FUNCTION__, mCameraId, strerror(-res), res);
1036 return res;
1037 }
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001038
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001039 if (mCaptureRequest.entryCount() == 0) {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001040 res = updateCaptureRequest(l.mParameters);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -07001041 if (res != OK) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001042 ALOGE("%s: Camera %d: Can't create still image capture request: "
1043 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -07001044 return res;
1045 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001046 }
1047
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001048 bool callbacksEnabled = l.mParameters.previewCallbackFlags &
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001049 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001050 bool recordingEnabled = (l.mParameters.state == Parameters::RECORD);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001051
1052 int streamSwitch = (callbacksEnabled ? 0x2 : 0x0) +
1053 (recordingEnabled ? 0x1 : 0x0);
1054 switch ( streamSwitch ) {
1055 case 0: { // No recording, callbacks
1056 uint8_t streamIds[2] = { mPreviewStreamId, mCaptureStreamId };
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001057 res = mCaptureRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS,
1058 streamIds, 2);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001059 break;
1060 }
1061 case 1: { // Recording
1062 uint8_t streamIds[3] = { mPreviewStreamId, mRecordingStreamId,
1063 mCaptureStreamId };
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001064 res = mCaptureRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS,
1065 streamIds, 3);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001066 break;
1067 }
1068 case 2: { // Callbacks
1069 uint8_t streamIds[3] = { mPreviewStreamId, mCallbackStreamId,
1070 mCaptureStreamId };
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001071 res = mCaptureRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS,
1072 streamIds, 3);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001073 break;
1074 }
1075 case 3: { // Both
1076 uint8_t streamIds[4] = { mPreviewStreamId, mCallbackStreamId,
1077 mRecordingStreamId, mCaptureStreamId };
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001078 res = mCaptureRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS,
1079 streamIds, 4);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001080 break;
1081 }
1082 };
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001083 if (res != OK) {
1084 ALOGE("%s: Camera %d: Unable to set up still image capture request: "
1085 "%s (%d)",
1086 __FUNCTION__, mCameraId, strerror(-res), res);
1087 return res;
1088 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001089 res = mCaptureRequest.sort();
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001090 if (res != OK) {
1091 ALOGE("%s: Camera %d: Unable to sort capture request: %s (%d)",
1092 __FUNCTION__, mCameraId, strerror(-res), res);
1093 return res;
1094 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001095
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001096 CameraMetadata captureCopy = mCaptureRequest;
1097 if (captureCopy.entryCount() == 0) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001098 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device",
1099 __FUNCTION__, mCameraId);
1100 return NO_MEMORY;
1101 }
1102
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001103 if (l.mParameters.state == Parameters::PREVIEW) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001104 res = mDevice->clearStreamingRequest();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001105 if (res != OK) {
1106 ALOGE("%s: Camera %d: Unable to stop preview for still capture: "
1107 "%s (%d)",
1108 __FUNCTION__, mCameraId, strerror(-res), res);
1109 return res;
1110 }
1111 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001112 // TODO: Capture should be atomic with setStreamingRequest here
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001113 res = mDevice->capture(captureCopy);
1114 if (res != OK) {
1115 ALOGE("%s: Camera %d: Unable to submit still image capture request: "
1116 "%s (%d)",
1117 __FUNCTION__, mCameraId, strerror(-res), res);
1118 return res;
1119 }
1120
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001121 switch (l.mParameters.state) {
1122 case Parameters::PREVIEW:
1123 l.mParameters.state = Parameters::STILL_CAPTURE;
1124 res = commandStopFaceDetectionL(l.mParameters);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001125 if (res != OK) {
1126 ALOGE("%s: Camera %d: Unable to stop face detection for still capture",
1127 __FUNCTION__, mCameraId);
1128 return res;
1129 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001130 break;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001131 case Parameters::RECORD:
1132 l.mParameters.state = Parameters::VIDEO_SNAPSHOT;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001133 break;
1134 default:
1135 ALOGE("%s: Camera %d: Unknown state for still capture!",
1136 __FUNCTION__, mCameraId);
1137 return INVALID_OPERATION;
1138 }
1139
1140 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001141}
1142
1143status_t Camera2Client::setParameters(const String8& params) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001144 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -07001145 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001146 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001147 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001148 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
1149
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001150 SharedParameters::Lock l(mParameters);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001151
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001152 res = l.mParameters.set(params);
1153 if (res != OK) return res;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001154
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001155 res = updateRequests(l.mParameters);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001156
1157 return res;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001158}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001159
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001160String8 Camera2Client::getParameters() const {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001161 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001162 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001163 if ( checkPid(__FUNCTION__) != OK) return String8();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001164
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001165 SharedParameters::ReadLock l(mParameters);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001166
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001167 // TODO: Deal with focus distances
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001168 return l.mParameters.paramsFlattened;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001169}
1170
1171status_t Camera2Client::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001172 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001173 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001174 status_t res;
1175 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001176
1177 ALOGV("%s: Camera %d: Command %d (%d, %d)", __FUNCTION__, mCameraId,
1178 cmd, arg1, arg2);
1179
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001180 switch (cmd) {
1181 case CAMERA_CMD_START_SMOOTH_ZOOM:
1182 return commandStartSmoothZoomL();
1183 case CAMERA_CMD_STOP_SMOOTH_ZOOM:
1184 return commandStopSmoothZoomL();
1185 case CAMERA_CMD_SET_DISPLAY_ORIENTATION:
1186 return commandSetDisplayOrientationL(arg1);
1187 case CAMERA_CMD_ENABLE_SHUTTER_SOUND:
1188 return commandEnableShutterSoundL(arg1 == 1);
1189 case CAMERA_CMD_PLAY_RECORDING_SOUND:
1190 return commandPlayRecordingSoundL();
1191 case CAMERA_CMD_START_FACE_DETECTION:
1192 return commandStartFaceDetectionL(arg1);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001193 case CAMERA_CMD_STOP_FACE_DETECTION: {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001194 SharedParameters::Lock l(mParameters);
1195 return commandStopFaceDetectionL(l.mParameters);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001196 }
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001197 case CAMERA_CMD_ENABLE_FOCUS_MOVE_MSG:
1198 return commandEnableFocusMoveMsgL(arg1 == 1);
1199 case CAMERA_CMD_PING:
1200 return commandPingL();
1201 case CAMERA_CMD_SET_VIDEO_BUFFER_COUNT:
1202 return commandSetVideoBufferCountL(arg1);
1203 default:
1204 ALOGE("%s: Unknown command %d (arguments %d, %d)",
1205 __FUNCTION__, cmd, arg1, arg2);
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001206 return BAD_VALUE;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001207 }
1208}
James Dong983cf232012-08-01 16:39:55 -07001209
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001210status_t Camera2Client::commandStartSmoothZoomL() {
1211 ALOGE("%s: Unimplemented!", __FUNCTION__);
1212 return OK;
1213}
James Dong983cf232012-08-01 16:39:55 -07001214
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001215status_t Camera2Client::commandStopSmoothZoomL() {
1216 ALOGE("%s: Unimplemented!", __FUNCTION__);
1217 return OK;
1218}
James Dong983cf232012-08-01 16:39:55 -07001219
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001220status_t Camera2Client::commandSetDisplayOrientationL(int degrees) {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001221 int transform = Parameters::degToTransform(degrees,
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001222 mCameraFacing == CAMERA_FACING_FRONT);
1223 if (transform == -1) {
1224 ALOGE("%s: Camera %d: Error setting %d as display orientation value",
1225 __FUNCTION__, mCameraId, degrees);
1226 return BAD_VALUE;
1227 }
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001228 SharedParameters::Lock l(mParameters);
1229 if (transform != l.mParameters.previewTransform &&
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001230 mPreviewStreamId != NO_STREAM) {
1231 mDevice->setStreamTransform(mPreviewStreamId, transform);
1232 }
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001233 l.mParameters.previewTransform = transform;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001234 return OK;
1235}
1236
1237status_t Camera2Client::commandEnableShutterSoundL(bool enable) {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001238 SharedParameters::Lock l(mParameters);
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001239 if (enable) {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001240 l.mParameters.playShutterSound = true;
James Dong983cf232012-08-01 16:39:55 -07001241 return OK;
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001242 }
1243
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001244 // Disabling shutter sound may not be allowed. In that case only
1245 // allow the mediaserver process to disable the sound.
1246 char value[PROPERTY_VALUE_MAX];
1247 property_get("ro.camera.sound.forced", value, "0");
1248 if (strncmp(value, "0", 2) != 0) {
1249 // Disabling shutter sound is not allowed. Deny if the current
1250 // process is not mediaserver.
1251 if (getCallingPid() != getpid()) {
1252 ALOGE("Failed to disable shutter sound. Permission denied (pid %d)",
1253 getCallingPid());
1254 return PERMISSION_DENIED;
1255 }
1256 }
1257
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001258 l.mParameters.playShutterSound = false;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001259 return OK;
1260}
1261
1262status_t Camera2Client::commandPlayRecordingSoundL() {
1263 mCameraService->playSound(CameraService::SOUND_RECORDING);
1264 return OK;
1265}
1266
1267status_t Camera2Client::commandStartFaceDetectionL(int type) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001268 ALOGV("%s: Camera %d: Starting face detection",
1269 __FUNCTION__, mCameraId);
1270 status_t res;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001271 SharedParameters::Lock l(mParameters);
1272 switch (l.mParameters.state) {
1273 case Parameters::DISCONNECTED:
1274 case Parameters::STOPPED:
1275 case Parameters::WAITING_FOR_PREVIEW_WINDOW:
1276 case Parameters::STILL_CAPTURE:
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001277 ALOGE("%s: Camera %d: Cannot start face detection without preview active",
1278 __FUNCTION__, mCameraId);
1279 return INVALID_OPERATION;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001280 case Parameters::PREVIEW:
1281 case Parameters::RECORD:
1282 case Parameters::VIDEO_SNAPSHOT:
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001283 // Good to go for starting face detect
1284 break;
1285 }
1286 // Ignoring type
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001287 if (l.mParameters.fastInfo.bestFaceDetectMode ==
1288 ANDROID_STATS_FACE_DETECTION_OFF) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001289 ALOGE("%s: Camera %d: Face detection not supported",
1290 __FUNCTION__, mCameraId);
1291 return INVALID_OPERATION;
1292 }
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001293 if (l.mParameters.enableFaceDetect) return OK;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001294
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001295 l.mParameters.enableFaceDetect = true;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001296
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001297 res = updateRequests(l.mParameters);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001298
1299 return res;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001300}
1301
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001302status_t Camera2Client::commandStopFaceDetectionL(Parameters &params) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001303 status_t res = OK;
1304 ALOGV("%s: Camera %d: Stopping face detection",
1305 __FUNCTION__, mCameraId);
1306
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001307 if (!params.enableFaceDetect) return OK;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001308
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001309 params.enableFaceDetect = false;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001310
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001311 if (params.state == Parameters::PREVIEW
1312 || params.state == Parameters::RECORD
1313 || params.state == Parameters::VIDEO_SNAPSHOT) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001314 res = updateRequests(params);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001315 }
1316
1317 return res;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001318}
1319
1320status_t Camera2Client::commandEnableFocusMoveMsgL(bool enable) {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001321 SharedParameters::Lock l(mParameters);
1322 l.mParameters.enableFocusMoveMessages = enable;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001323
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001324 return OK;
1325}
1326
1327status_t Camera2Client::commandPingL() {
1328 // Always ping back if access is proper and device is alive
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001329 SharedParameters::Lock l(mParameters);
1330 if (l.mParameters.state != Parameters::DISCONNECTED) {
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001331 return OK;
1332 } else {
1333 return NO_INIT;
1334 }
1335}
1336
1337status_t Camera2Client::commandSetVideoBufferCountL(size_t count) {
James Dong8da4cd72012-08-04 19:58:07 -07001338 if (recordingEnabledL()) {
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001339 ALOGE("%s: Camera %d: Error setting video buffer count after "
1340 "recording was started", __FUNCTION__, mCameraId);
1341 return INVALID_OPERATION;
1342 }
1343
1344 // 32 is the current upper limit on the video buffer count for BufferQueue
1345 if (count > 32) {
1346 ALOGE("%s: Camera %d: Error setting %d as video buffer count value",
1347 __FUNCTION__, mCameraId, count);
1348 return BAD_VALUE;
1349 }
1350
1351 // Need to reallocate memory for heap
1352 if (mRecordingHeapCount != count) {
1353 if (mRecordingHeap != 0) {
1354 mRecordingHeap.clear();
1355 mRecordingHeap = NULL;
1356 }
1357 mRecordingHeapCount = count;
1358 }
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001359
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001360 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001361}
1362
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001363/** Device-related methods */
1364
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -07001365void Camera2Client::notifyError(int errorCode, int arg1, int arg2) {
1366 ALOGE("Error condition %d reported by HAL, arguments %d, %d", errorCode, arg1, arg2);
1367}
1368
1369void Camera2Client::notifyShutter(int frameNumber, nsecs_t timestamp) {
1370 ALOGV("%s: Shutter notification for frame %d at time %lld", __FUNCTION__,
1371 frameNumber, timestamp);
1372}
1373
1374void Camera2Client::notifyAutoFocus(uint8_t newState, int triggerId) {
1375 ALOGV("%s: Autofocus state now %d, last trigger %d",
1376 __FUNCTION__, newState, triggerId);
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001377 bool sendCompletedMessage = false;
1378 bool sendMovingMessage = false;
1379
1380 bool success = false;
1381 bool afInMotion = false;
1382 {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001383 SharedParameters::Lock l(mParameters);
1384 switch (l.mParameters.focusMode) {
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001385 case Parameters::FOCUS_MODE_AUTO:
1386 case Parameters::FOCUS_MODE_MACRO:
1387 // Don't send notifications upstream if they're not for the current AF
1388 // trigger. For example, if cancel was called in between, or if we
1389 // already sent a notification about this AF call.
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001390 if (triggerId != l.mParameters.currentAfTriggerId) break;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001391 switch (newState) {
1392 case ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED:
1393 success = true;
1394 // no break
1395 case ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
1396 sendCompletedMessage = true;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001397 l.mParameters.currentAfTriggerId = -1;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001398 break;
1399 case ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN:
1400 // Just starting focusing, ignore
1401 break;
1402 case ANDROID_CONTROL_AF_STATE_INACTIVE:
1403 case ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN:
1404 case ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED:
1405 default:
1406 // Unexpected in AUTO/MACRO mode
1407 ALOGE("%s: Unexpected AF state transition in AUTO/MACRO mode: %d",
1408 __FUNCTION__, newState);
1409 break;
1410 }
1411 break;
1412 case Parameters::FOCUS_MODE_CONTINUOUS_VIDEO:
1413 case Parameters::FOCUS_MODE_CONTINUOUS_PICTURE:
1414 switch (newState) {
1415 case ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED:
1416 success = true;
1417 // no break
1418 case ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
1419 // Don't send notifications upstream if they're not for
1420 // the current AF trigger. For example, if cancel was
1421 // called in between, or if we already sent a
1422 // notification about this AF call.
1423 // Send both a 'AF done' callback and a 'AF move' callback
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001424 if (triggerId != l.mParameters.currentAfTriggerId) break;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001425 sendCompletedMessage = true;
1426 afInMotion = false;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001427 if (l.mParameters.enableFocusMoveMessages &&
1428 l.mParameters.afInMotion) {
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001429 sendMovingMessage = true;
1430 }
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001431 l.mParameters.currentAfTriggerId = -1;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001432 break;
1433 case ANDROID_CONTROL_AF_STATE_INACTIVE:
1434 // Cancel was called, or we switched state; care if
1435 // currently moving
1436 afInMotion = false;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001437 if (l.mParameters.enableFocusMoveMessages &&
1438 l.mParameters.afInMotion) {
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001439 sendMovingMessage = true;
1440 }
1441 break;
1442 case ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN:
1443 // Start passive scan, inform upstream
1444 afInMotion = true;
1445 // no break
1446 case ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED:
1447 // Stop passive scan, inform upstream
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001448 if (l.mParameters.enableFocusMoveMessages) {
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001449 sendMovingMessage = true;
1450 }
1451 break;
1452 }
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001453 l.mParameters.afInMotion = afInMotion;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001454 break;
1455 case Parameters::FOCUS_MODE_EDOF:
1456 case Parameters::FOCUS_MODE_INFINITY:
1457 case Parameters::FOCUS_MODE_FIXED:
1458 default:
1459 if (newState != ANDROID_CONTROL_AF_STATE_INACTIVE) {
1460 ALOGE("%s: Unexpected AF state change %d (ID %d) in focus mode %d",
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001461 __FUNCTION__, newState, triggerId, l.mParameters.focusMode);
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001462 }
1463 }
1464 }
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001465 if (sendMovingMessage) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001466 Mutex::Autolock iccl(mICameraClientLock);
1467 if (mCameraClient != 0) {
1468 mCameraClient->notifyCallback(CAMERA_MSG_FOCUS_MOVE,
1469 afInMotion ? 1 : 0, 0);
1470 }
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001471 }
Eino-Ville Talvala603b12e2012-08-08 09:25:58 -07001472 if (sendCompletedMessage) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001473 Mutex::Autolock iccl(mICameraClientLock);
1474 if (mCameraClient != 0) {
1475 mCameraClient->notifyCallback(CAMERA_MSG_FOCUS, success ? 1 : 0, 0);
1476 }
Eino-Ville Talvala603b12e2012-08-08 09:25:58 -07001477 }
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -07001478}
1479
1480void Camera2Client::notifyAutoExposure(uint8_t newState, int triggerId) {
1481 ALOGV("%s: Autoexposure state now %d, last trigger %d",
1482 __FUNCTION__, newState, triggerId);
1483}
1484
1485void Camera2Client::notifyAutoWhitebalance(uint8_t newState, int triggerId) {
1486 ALOGV("%s: Auto-whitebalance state now %d, last trigger %d",
1487 __FUNCTION__, newState, triggerId);
1488}
1489
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -07001490Camera2Client::FrameProcessor::FrameProcessor(wp<Camera2Client> client):
1491 Thread(false), mClient(client) {
1492}
1493
1494Camera2Client::FrameProcessor::~FrameProcessor() {
1495 ALOGV("%s: Exit", __FUNCTION__);
1496}
1497
1498void Camera2Client::FrameProcessor::dump(int fd, const Vector<String16>& args) {
1499 String8 result(" Latest received frame:\n");
1500 write(fd, result.string(), result.size());
1501 mLastFrame.dump(fd, 2, 6);
1502}
1503
1504bool Camera2Client::FrameProcessor::threadLoop() {
1505 status_t res;
1506
1507 sp<Camera2Device> device;
1508 {
1509 sp<Camera2Client> client = mClient.promote();
1510 if (client == 0) return false;
1511 device = client->mDevice;
1512 }
1513
1514 res = device->waitForNextFrame(kWaitDuration);
1515 if (res == OK) {
1516 sp<Camera2Client> client = mClient.promote();
1517 if (client == 0) return false;
1518 processNewFrames(client);
1519 } else if (res != TIMED_OUT) {
1520 ALOGE("Camera2Client::FrameProcessor: Error waiting for new "
1521 "frames: %s (%d)", strerror(-res), res);
1522 }
1523
1524 return true;
1525}
1526
1527void Camera2Client::FrameProcessor::processNewFrames(sp<Camera2Client> &client) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001528 status_t res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001529 CameraMetadata frame;
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -07001530 while ( (res = client->mDevice->getNextFrame(&frame)) == OK) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001531 camera_metadata_entry_t entry;
1532 entry = frame.find(ANDROID_REQUEST_FRAME_COUNT);
1533 if (entry.count == 0) {
1534 ALOGE("%s: Camera %d: Error reading frame number: %s (%d)",
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -07001535 __FUNCTION__, client->mCameraId, strerror(-res), res);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001536 break;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001537 }
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001538
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -07001539 res = processFaceDetect(frame, client);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001540 if (res != OK) break;
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -07001541
1542 mLastFrame.acquire(frame);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001543 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001544 if (res != NOT_ENOUGH_DATA) {
1545 ALOGE("%s: Camera %d: Error getting next frame: %s (%d)",
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -07001546 __FUNCTION__, client->mCameraId, strerror(-res), res);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001547 return;
1548 }
1549
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001550 return;
1551}
1552
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -07001553status_t Camera2Client::FrameProcessor::processFaceDetect(
1554 const CameraMetadata &frame, sp<Camera2Client> &client) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001555 status_t res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001556 camera_metadata_ro_entry_t entry;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001557 bool enableFaceDetect;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001558 int maxFaces;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001559 {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001560 SharedParameters::Lock l(client->mParameters);
1561 enableFaceDetect = l.mParameters.enableFaceDetect;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001562 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001563 entry = frame.find(ANDROID_STATS_FACE_DETECT_MODE);
1564
1565 // TODO: This should be an error once implementations are compliant
1566 if (entry.count == 0) {
Eino-Ville Talvala76dc8da2012-08-21 16:09:31 -07001567 return OK;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001568 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001569
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001570 uint8_t faceDetectMode = entry.data.u8[0];
1571
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001572 camera_frame_metadata metadata;
1573 Vector<camera_face_t> faces;
1574 metadata.number_of_faces = 0;
1575
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001576 if (enableFaceDetect && faceDetectMode != ANDROID_STATS_FACE_DETECTION_OFF) {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001577 SharedParameters::Lock l(client->mParameters);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001578 entry = frame.find(ANDROID_STATS_FACE_RECTANGLES);
1579 if (entry.count == 0) {
1580 ALOGE("%s: Camera %d: Unable to read face rectangles",
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -07001581 __FUNCTION__, client->mCameraId);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001582 return res;
1583 }
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001584 metadata.number_of_faces = entry.count / 4;
1585 if (metadata.number_of_faces >
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001586 l.mParameters.fastInfo.maxFaces) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001587 ALOGE("%s: Camera %d: More faces than expected! (Got %d, max %d)",
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -07001588 __FUNCTION__, client->mCameraId,
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001589 metadata.number_of_faces, l.mParameters.fastInfo.maxFaces);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001590 return res;
1591 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001592 const int32_t *faceRects = entry.data.i32;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001593
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001594 entry = frame.find(ANDROID_STATS_FACE_SCORES);
1595 if (entry.count == 0) {
1596 ALOGE("%s: Camera %d: Unable to read face scores",
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -07001597 __FUNCTION__, client->mCameraId);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001598 return res;
1599 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001600 const uint8_t *faceScores = entry.data.u8;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001601
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001602 const int32_t *faceLandmarks = NULL;
1603 const int32_t *faceIds = NULL;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001604
1605 if (faceDetectMode == ANDROID_STATS_FACE_DETECTION_FULL) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001606 entry = frame.find(ANDROID_STATS_FACE_LANDMARKS);
1607 if (entry.count == 0) {
1608 ALOGE("%s: Camera %d: Unable to read face landmarks",
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -07001609 __FUNCTION__, client->mCameraId);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001610 return res;
1611 }
1612 faceLandmarks = entry.data.i32;
1613
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001614 entry = frame.find(ANDROID_STATS_FACE_IDS);
1615
1616 if (entry.count == 0) {
1617 ALOGE("%s: Camera %d: Unable to read face IDs",
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -07001618 __FUNCTION__, client->mCameraId);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001619 return res;
1620 }
1621 faceIds = entry.data.i32;
1622 }
1623
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001624 faces.setCapacity(metadata.number_of_faces);
1625
1626 for (int i = 0; i < metadata.number_of_faces; i++) {
1627 camera_face_t face;
1628
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001629 face.rect[0] = l.mParameters.arrayXToNormalized(faceRects[i*4 + 0]);
1630 face.rect[1] = l.mParameters.arrayYToNormalized(faceRects[i*4 + 1]);
1631 face.rect[2] = l.mParameters.arrayXToNormalized(faceRects[i*4 + 2]);
1632 face.rect[3] = l.mParameters.arrayYToNormalized(faceRects[i*4 + 3]);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001633
1634 face.score = faceScores[i];
1635 if (faceDetectMode == ANDROID_STATS_FACE_DETECTION_FULL) {
1636 face.id = faceIds[i];
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -07001637 face.left_eye[0] =
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001638 l.mParameters.arrayXToNormalized(faceLandmarks[i*6 + 0]);
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -07001639 face.left_eye[1] =
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001640 l.mParameters.arrayYToNormalized(faceLandmarks[i*6 + 1]);
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -07001641 face.right_eye[0] =
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001642 l.mParameters.arrayXToNormalized(faceLandmarks[i*6 + 2]);
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -07001643 face.right_eye[1] =
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001644 l.mParameters.arrayYToNormalized(faceLandmarks[i*6 + 3]);
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -07001645 face.mouth[0] =
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001646 l.mParameters.arrayXToNormalized(faceLandmarks[i*6 + 4]);
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -07001647 face.mouth[1] =
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001648 l.mParameters.arrayYToNormalized(faceLandmarks[i*6 + 5]);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001649 } else {
1650 face.id = 0;
1651 face.left_eye[0] = face.left_eye[1] = -2000;
1652 face.right_eye[0] = face.right_eye[1] = -2000;
1653 face.mouth[0] = face.mouth[1] = -2000;
1654 }
1655 faces.push_back(face);
1656 }
1657
1658 metadata.faces = faces.editArray();
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001659 }
1660
1661 if (metadata.number_of_faces != 0) {
1662 Mutex::Autolock iccl(client->mICameraClientLock);
1663 if (client->mCameraClient != NULL) {
1664 client->mCameraClient->dataCallback(CAMERA_MSG_PREVIEW_METADATA,
1665 NULL, &metadata);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001666 }
1667 }
1668 return OK;
1669}
1670
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001671void Camera2Client::onCallbackAvailable() {
1672 ATRACE_CALL();
1673 status_t res;
1674 ALOGV("%s: Camera %d: Preview callback available", __FUNCTION__, mCameraId);
1675
1676 int callbackHeapId;
1677 sp<Camera2Heap> callbackHeap;
1678 size_t heapIdx;
1679
1680 CpuConsumer::LockedBuffer imgBuffer;
1681 ALOGV("%s: Getting buffer", __FUNCTION__);
1682 res = mCallbackConsumer->lockNextBuffer(&imgBuffer);
1683 if (res != OK) {
1684 ALOGE("%s: Camera %d: Error receiving next callback buffer: "
1685 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
1686 return;
1687 }
1688
1689 {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001690 SharedParameters::Lock l(mParameters);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001691
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001692 if ( l.mParameters.state != Parameters::PREVIEW
1693 && l.mParameters.state != Parameters::RECORD
1694 && l.mParameters.state != Parameters::VIDEO_SNAPSHOT) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001695 ALOGV("%s: Camera %d: No longer streaming",
1696 __FUNCTION__, mCameraId);
1697 mCallbackConsumer->unlockBuffer(imgBuffer);
1698 return;
1699 }
1700
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001701 if (! (l.mParameters.previewCallbackFlags &
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001702 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) ) {
1703 ALOGV("%s: No longer enabled, dropping", __FUNCTION__);
1704 mCallbackConsumer->unlockBuffer(imgBuffer);
1705 return;
1706 }
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001707 if ((l.mParameters.previewCallbackFlags &
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001708 CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) &&
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001709 !l.mParameters.previewCallbackOneShot) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001710 ALOGV("%s: One shot mode, already sent, dropping", __FUNCTION__);
1711 mCallbackConsumer->unlockBuffer(imgBuffer);
1712 return;
1713 }
1714
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001715 if (imgBuffer.format != l.mParameters.previewFormat) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001716 ALOGE("%s: Camera %d: Unexpected format for callback: "
1717 "%x, expected %x", __FUNCTION__, mCameraId,
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001718 imgBuffer.format, l.mParameters.previewFormat);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001719 mCallbackConsumer->unlockBuffer(imgBuffer);
1720 return;
1721 }
1722
1723 size_t bufferSize = calculateBufferSize(imgBuffer.width, imgBuffer.height,
1724 imgBuffer.format, imgBuffer.stride);
1725 size_t currentBufferSize = (mCallbackHeap == 0) ?
1726 0 : (mCallbackHeap->mHeap->getSize() / kCallbackHeapCount);
1727 if (bufferSize != currentBufferSize) {
1728 mCallbackHeap.clear();
1729 mCallbackHeap = new Camera2Heap(bufferSize, kCallbackHeapCount,
1730 "Camera2Client::CallbackHeap");
1731 if (mCallbackHeap->mHeap->getSize() == 0) {
1732 ALOGE("%s: Camera %d: Unable to allocate memory for callbacks",
1733 __FUNCTION__, mCameraId);
1734 mCallbackConsumer->unlockBuffer(imgBuffer);
1735 return;
1736 }
1737
1738 mCallbackHeapHead = 0;
1739 mCallbackHeapFree = kCallbackHeapCount;
1740 mCallbackHeapId++;
1741 }
1742
1743 if (mCallbackHeapFree == 0) {
1744 ALOGE("%s: Camera %d: No free callback buffers, dropping frame",
1745 __FUNCTION__, mCameraId);
1746 mCallbackConsumer->unlockBuffer(imgBuffer);
1747 return;
1748 }
1749 heapIdx = mCallbackHeapHead;
1750 callbackHeap = mCallbackHeap;
1751 callbackHeapId = mCallbackHeapId;
1752
1753 mCallbackHeapHead = (mCallbackHeapHead + 1) & kCallbackHeapCount;
1754 mCallbackHeapFree--;
1755
1756 // TODO: Get rid of this memcpy by passing the gralloc queue all the way
1757 // to app
1758
1759 ssize_t offset;
1760 size_t size;
1761 sp<IMemoryHeap> heap =
1762 mCallbackHeap->mBuffers[heapIdx]->getMemory(&offset,
1763 &size);
1764 uint8_t *data = (uint8_t*)heap->getBase() + offset;
1765 memcpy(data, imgBuffer.data, bufferSize);
1766
1767 ALOGV("%s: Freeing buffer", __FUNCTION__);
1768 mCallbackConsumer->unlockBuffer(imgBuffer);
1769
1770 // In one-shot mode, stop sending callbacks after the first one
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001771 if (l.mParameters.previewCallbackFlags &
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001772 CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) {
1773 ALOGV("%s: clearing oneshot", __FUNCTION__);
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001774 l.mParameters.previewCallbackOneShot = false;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001775 }
1776 }
1777
1778 // Call outside parameter lock to allow re-entrancy from notification
1779 {
1780 Mutex::Autolock iccl(mICameraClientLock);
1781 if (mCameraClient != 0) {
1782 ALOGV("%s: Camera %d: Invoking client data callback",
1783 __FUNCTION__, mCameraId);
1784 mCameraClient->dataCallback(CAMERA_MSG_PREVIEW_FRAME,
1785 callbackHeap->mBuffers[heapIdx], NULL);
1786 }
1787 }
1788
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001789 SharedParameters::Lock l(mParameters);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001790 // Only increment free if we're still using the same heap
1791 if (mCallbackHeapId == callbackHeapId) {
1792 mCallbackHeapFree++;
1793 }
1794
1795 ALOGV("%s: exit", __FUNCTION__);
1796}
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001797
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001798void Camera2Client::onCaptureAvailable() {
1799 ATRACE_CALL();
1800 status_t res;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001801 sp<Camera2Heap> captureHeap;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001802 ALOGV("%s: Camera %d: Still capture available", __FUNCTION__, mCameraId);
1803
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001804 {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001805 SharedParameters::Lock l(mParameters);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001806 CpuConsumer::LockedBuffer imgBuffer;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001807
1808 res = mCaptureConsumer->lockNextBuffer(&imgBuffer);
1809 if (res != OK) {
1810 ALOGE("%s: Camera %d: Error receiving still image buffer: %s (%d)",
1811 __FUNCTION__, mCameraId, strerror(-res), res);
1812 return;
1813 }
1814
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001815 // TODO: Signal errors here upstream
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001816 if (l.mParameters.state != Parameters::STILL_CAPTURE &&
1817 l.mParameters.state != Parameters::VIDEO_SNAPSHOT) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001818 ALOGE("%s: Camera %d: Still image produced unexpectedly!",
1819 __FUNCTION__, mCameraId);
1820 mCaptureConsumer->unlockBuffer(imgBuffer);
1821 return;
1822 }
1823
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001824 if (imgBuffer.format != HAL_PIXEL_FORMAT_BLOB) {
1825 ALOGE("%s: Camera %d: Unexpected format for still image: "
1826 "%x, expected %x", __FUNCTION__, mCameraId,
1827 imgBuffer.format,
1828 HAL_PIXEL_FORMAT_BLOB);
1829 mCaptureConsumer->unlockBuffer(imgBuffer);
1830 return;
1831 }
1832
1833 // TODO: Optimize this to avoid memcopy
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001834 void* captureMemory = mCaptureHeap->mHeap->getBase();
1835 size_t size = mCaptureHeap->mHeap->getSize();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001836 memcpy(captureMemory, imgBuffer.data, size);
1837
1838 mCaptureConsumer->unlockBuffer(imgBuffer);
1839
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001840 switch (l.mParameters.state) {
1841 case Parameters::STILL_CAPTURE:
1842 l.mParameters.state = Parameters::STOPPED;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001843 break;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001844 case Parameters::VIDEO_SNAPSHOT:
1845 l.mParameters.state = Parameters::RECORD;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001846 break;
1847 default:
1848 ALOGE("%s: Camera %d: Unexpected state %d", __FUNCTION__,
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001849 mCameraId, l.mParameters.state);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001850 break;
1851 }
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001852
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001853 captureHeap = mCaptureHeap;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001854 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001855 // Call outside parameter locks to allow re-entrancy from notification
1856 Mutex::Autolock iccl(mICameraClientLock);
1857 if (mCameraClient != 0) {
1858 mCameraClient->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE,
1859 captureHeap->mBuffers[0], NULL);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001860 }
1861}
1862
1863void Camera2Client::onRecordingFrameAvailable() {
1864 ATRACE_CALL();
1865 status_t res;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001866 sp<Camera2Heap> recordingHeap;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001867 size_t heapIdx = 0;
1868 nsecs_t timestamp;
1869 {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001870 SharedParameters::Lock l(mParameters);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001871
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07001872 BufferItemConsumer::BufferItem imgBuffer;
1873 res = mRecordingConsumer->acquireBuffer(&imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001874 if (res != OK) {
1875 ALOGE("%s: Camera %d: Error receiving recording buffer: %s (%d)",
1876 __FUNCTION__, mCameraId, strerror(-res), res);
1877 return;
1878 }
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07001879 timestamp = imgBuffer.mTimestamp;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001880
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001881 mRecordingFrameCount++;
1882 ALOGV("OnRecordingFrame: Frame %d", mRecordingFrameCount);
1883
1884 // TODO: Signal errors here upstream
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001885 if (l.mParameters.state != Parameters::RECORD &&
1886 l.mParameters.state != Parameters::VIDEO_SNAPSHOT) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001887 ALOGV("%s: Camera %d: Discarding recording image buffers received after "
1888 "recording done",
1889 __FUNCTION__, mCameraId);
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07001890 mRecordingConsumer->releaseBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001891 return;
1892 }
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001893
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001894 if (mRecordingHeap == 0) {
1895 const size_t bufferSize = 4 + sizeof(buffer_handle_t);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001896 ALOGV("%s: Camera %d: Creating recording heap with %d buffers of "
1897 "size %d bytes", __FUNCTION__, mCameraId,
James Dong983cf232012-08-01 16:39:55 -07001898 mRecordingHeapCount, bufferSize);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001899
James Dong983cf232012-08-01 16:39:55 -07001900 mRecordingHeap = new Camera2Heap(bufferSize, mRecordingHeapCount,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001901 "Camera2Client::RecordingHeap");
1902 if (mRecordingHeap->mHeap->getSize() == 0) {
1903 ALOGE("%s: Camera %d: Unable to allocate memory for recording",
1904 __FUNCTION__, mCameraId);
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07001905 mRecordingConsumer->releaseBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001906 return;
1907 }
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07001908 for (size_t i = 0; i < mRecordingBuffers.size(); i++) {
1909 if (mRecordingBuffers[i].mBuf !=
1910 BufferItemConsumer::INVALID_BUFFER_SLOT) {
1911 ALOGE("%s: Camera %d: Non-empty recording buffers list!",
1912 __FUNCTION__, mCameraId);
1913 }
1914 }
1915 mRecordingBuffers.clear();
1916 mRecordingBuffers.setCapacity(mRecordingHeapCount);
1917 mRecordingBuffers.insertAt(0, mRecordingHeapCount);
1918
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001919 mRecordingHeapHead = 0;
James Dong983cf232012-08-01 16:39:55 -07001920 mRecordingHeapFree = mRecordingHeapCount;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001921 }
1922
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001923 if ( mRecordingHeapFree == 0) {
1924 ALOGE("%s: Camera %d: No free recording buffers, dropping frame",
1925 __FUNCTION__, mCameraId);
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07001926 mRecordingConsumer->releaseBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001927 return;
1928 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001929
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001930 heapIdx = mRecordingHeapHead;
James Dong983cf232012-08-01 16:39:55 -07001931 mRecordingHeapHead = (mRecordingHeapHead + 1) % mRecordingHeapCount;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001932 mRecordingHeapFree--;
1933
1934 ALOGV("%s: Camera %d: Timestamp %lld",
1935 __FUNCTION__, mCameraId, timestamp);
1936
1937 ssize_t offset;
1938 size_t size;
1939 sp<IMemoryHeap> heap =
1940 mRecordingHeap->mBuffers[heapIdx]->getMemory(&offset,
1941 &size);
1942
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001943 uint8_t *data = (uint8_t*)heap->getBase() + offset;
1944 uint32_t type = kMetadataBufferTypeGrallocSource;
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07001945 *((uint32_t*)data) = type;
1946 *((buffer_handle_t*)(data + 4)) = imgBuffer.mGraphicBuffer->handle;
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001947 ALOGV("%s: Camera %d: Sending out buffer_handle_t %p",
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07001948 __FUNCTION__, mCameraId, imgBuffer.mGraphicBuffer->handle);
1949 mRecordingBuffers.replaceAt(imgBuffer, heapIdx);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001950 recordingHeap = mRecordingHeap;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001951 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001952
1953 // Call outside locked parameters to allow re-entrancy from notification
1954 Mutex::Autolock iccl(mICameraClientLock);
1955 if (mCameraClient != 0) {
1956 mCameraClient->dataCallbackTimestamp(timestamp,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001957 CAMERA_MSG_VIDEO_FRAME,
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001958 recordingHeap->mBuffers[heapIdx]);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001959 }
1960}
1961
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001962/** Utility methods */
1963
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001964status_t Camera2Client::updateRequests(const Parameters &params) {
1965 status_t res;
1966
1967 res = updatePreviewRequest(params);
1968 if (res != OK) {
1969 ALOGE("%s: Camera %d: Unable to update preview request: %s (%d)",
1970 __FUNCTION__, mCameraId, strerror(-res), res);
1971 return res;
1972 }
1973 res = updateCaptureRequest(params);
1974 if (res != OK) {
1975 ALOGE("%s: Camera %d: Unable to update capture request: %s (%d)",
1976 __FUNCTION__, mCameraId, strerror(-res), res);
1977 return res;
1978 }
1979
1980 res = updateRecordingRequest(params);
1981 if (res != OK) {
1982 ALOGE("%s: Camera %d: Unable to update recording request: %s (%d)",
1983 __FUNCTION__, mCameraId, strerror(-res), res);
1984 return res;
1985 }
1986
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001987 if (params.state == Parameters::PREVIEW) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001988 res = mDevice->setStreamingRequest(mPreviewRequest);
1989 if (res != OK) {
1990 ALOGE("%s: Camera %d: Error streaming new preview request: %s (%d)",
1991 __FUNCTION__, mCameraId, strerror(-res), res);
1992 return res;
1993 }
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001994 } else if (params.state == Parameters::RECORD ||
1995 params.state == Parameters::VIDEO_SNAPSHOT) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001996 res = mDevice->setStreamingRequest(mRecordingRequest);
1997 if (res != OK) {
1998 ALOGE("%s: Camera %d: Error streaming new record request: %s (%d)",
1999 __FUNCTION__, mCameraId, strerror(-res), res);
2000 return res;
2001 }
2002 }
2003 return res;
2004}
2005
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002006status_t Camera2Client::updatePreviewStream(const Parameters &params) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002007 ATRACE_CALL();
2008 status_t res;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002009
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002010 if (mPreviewStreamId != NO_STREAM) {
2011 // Check if stream parameters have to change
2012 uint32_t currentWidth, currentHeight;
2013 res = mDevice->getStreamInfo(mPreviewStreamId,
2014 &currentWidth, &currentHeight, 0);
2015 if (res != OK) {
2016 ALOGE("%s: Camera %d: Error querying preview stream info: "
2017 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2018 return res;
2019 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002020 if (currentWidth != (uint32_t)params.previewWidth ||
2021 currentHeight != (uint32_t)params.previewHeight) {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -07002022 ALOGV("%s: Camera %d: Preview size switch: %d x %d -> %d x %d",
2023 __FUNCTION__, mCameraId, currentWidth, currentHeight,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002024 params.previewWidth, params.previewHeight);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002025 res = mDevice->waitUntilDrained();
2026 if (res != OK) {
2027 ALOGE("%s: Camera %d: Error waiting for preview to drain: "
2028 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2029 return res;
2030 }
2031 res = mDevice->deleteStream(mPreviewStreamId);
2032 if (res != OK) {
2033 ALOGE("%s: Camera %d: Unable to delete old output stream "
2034 "for preview: %s (%d)", __FUNCTION__, mCameraId,
2035 strerror(-res), res);
2036 return res;
2037 }
2038 mPreviewStreamId = NO_STREAM;
2039 }
2040 }
2041
2042 if (mPreviewStreamId == NO_STREAM) {
2043 res = mDevice->createStream(mPreviewWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002044 params.previewWidth, params.previewHeight,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002045 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0,
2046 &mPreviewStreamId);
2047 if (res != OK) {
2048 ALOGE("%s: Camera %d: Unable to create preview stream: %s (%d)",
2049 __FUNCTION__, mCameraId, strerror(-res), res);
2050 return res;
2051 }
2052 }
2053
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07002054 res = mDevice->setStreamTransform(mPreviewStreamId,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002055 params.previewTransform);
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07002056 if (res != OK) {
2057 ALOGE("%s: Camera %d: Unable to set preview stream transform: "
2058 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2059 return res;
2060 }
2061
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002062 return OK;
2063}
2064
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002065status_t Camera2Client::updatePreviewRequest(const Parameters &params) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07002066 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002067 status_t res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002068 if (mPreviewRequest.entryCount() == 0) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002069 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
2070 &mPreviewRequest);
2071 if (res != OK) {
2072 ALOGE("%s: Camera %d: Unable to create default preview request: "
2073 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2074 return res;
2075 }
2076 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002077
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002078 res = updateRequestCommon(&mPreviewRequest, params);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002079 if (res != OK) {
2080 ALOGE("%s: Camera %d: Unable to update common entries of preview "
2081 "request: %s (%d)", __FUNCTION__, mCameraId,
2082 strerror(-res), res);
2083 return res;
2084 }
2085
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07002086 return OK;
2087}
2088
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002089status_t Camera2Client::updateCallbackStream(const Parameters &params) {
2090 status_t res;
2091
2092 if (mCallbackConsumer == 0) {
2093 // Create CPU buffer queue endpoint
2094 mCallbackConsumer = new CpuConsumer(kCallbackHeapCount);
2095 mCallbackWaiter = new CallbackWaiter(this);
2096 mCallbackConsumer->setFrameAvailableListener(mCallbackWaiter);
2097 mCallbackConsumer->setName(String8("Camera2Client::CallbackConsumer"));
2098 mCallbackWindow = new SurfaceTextureClient(
2099 mCallbackConsumer->getProducerInterface());
2100 }
2101
2102 if (mCallbackStreamId != NO_STREAM) {
2103 // Check if stream parameters have to change
2104 uint32_t currentWidth, currentHeight, currentFormat;
2105 res = mDevice->getStreamInfo(mCallbackStreamId,
2106 &currentWidth, &currentHeight, &currentFormat);
2107 if (res != OK) {
2108 ALOGE("%s: Camera %d: Error querying callback output stream info: "
2109 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2110 return res;
2111 }
2112 if (currentWidth != (uint32_t)params.previewWidth ||
2113 currentHeight != (uint32_t)params.previewHeight ||
2114 currentFormat != (uint32_t)params.previewFormat) {
2115 // Since size should only change while preview is not running,
2116 // assuming that all existing use of old callback stream is
2117 // completed.
2118 res = mDevice->deleteStream(mCallbackStreamId);
2119 if (res != OK) {
2120 ALOGE("%s: Camera %d: Unable to delete old output stream "
2121 "for callbacks: %s (%d)", __FUNCTION__, mCameraId,
2122 strerror(-res), res);
2123 return res;
2124 }
2125 mCallbackStreamId = NO_STREAM;
2126 }
2127 }
2128
2129 if (mCallbackStreamId == NO_STREAM) {
2130 ALOGV("Creating callback stream: %d %d format 0x%x",
2131 params.previewWidth, params.previewHeight,
2132 params.previewFormat);
2133 res = mDevice->createStream(mCallbackWindow,
2134 params.previewWidth, params.previewHeight,
2135 params.previewFormat, 0, &mCallbackStreamId);
2136 if (res != OK) {
2137 ALOGE("%s: Camera %d: Can't create output stream for callbacks: "
2138 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2139 return res;
2140 }
2141 }
2142
2143 return OK;
2144}
2145
2146
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002147status_t Camera2Client::updateCaptureStream(const Parameters &params) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002148 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002149 status_t res;
2150 // Find out buffer size for JPEG
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002151 camera_metadata_ro_entry_t maxJpegSize =
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07002152 mParameters.staticInfo(ANDROID_JPEG_MAX_SIZE);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002153 if (maxJpegSize.count == 0) {
2154 ALOGE("%s: Camera %d: Can't find ANDROID_JPEG_MAX_SIZE!",
2155 __FUNCTION__, mCameraId);
2156 return INVALID_OPERATION;
2157 }
2158
2159 if (mCaptureConsumer == 0) {
2160 // Create CPU buffer queue endpoint
2161 mCaptureConsumer = new CpuConsumer(1);
2162 mCaptureConsumer->setFrameAvailableListener(new CaptureWaiter(this));
2163 mCaptureConsumer->setName(String8("Camera2Client::CaptureConsumer"));
2164 mCaptureWindow = new SurfaceTextureClient(
2165 mCaptureConsumer->getProducerInterface());
2166 // Create memory for API consumption
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002167 mCaptureHeap = new Camera2Heap(maxJpegSize.data.i32[0], 1,
2168 "Camera2Client::CaptureHeap");
2169 if (mCaptureHeap->mHeap->getSize() == 0) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002170 ALOGE("%s: Camera %d: Unable to allocate memory for capture",
2171 __FUNCTION__, mCameraId);
2172 return NO_MEMORY;
2173 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002174 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002175
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002176 if (mCaptureStreamId != NO_STREAM) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002177 // Check if stream parameters have to change
2178 uint32_t currentWidth, currentHeight;
2179 res = mDevice->getStreamInfo(mCaptureStreamId,
2180 &currentWidth, &currentHeight, 0);
2181 if (res != OK) {
2182 ALOGE("%s: Camera %d: Error querying capture output stream info: "
2183 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2184 return res;
2185 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002186 if (currentWidth != (uint32_t)params.pictureWidth ||
2187 currentHeight != (uint32_t)params.pictureHeight) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002188 res = mDevice->deleteStream(mCaptureStreamId);
2189 if (res != OK) {
2190 ALOGE("%s: Camera %d: Unable to delete old output stream "
2191 "for capture: %s (%d)", __FUNCTION__, mCameraId,
2192 strerror(-res), res);
2193 return res;
2194 }
2195 mCaptureStreamId = NO_STREAM;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002196 }
2197 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002198
2199 if (mCaptureStreamId == NO_STREAM) {
2200 // Create stream for HAL production
2201 res = mDevice->createStream(mCaptureWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002202 params.pictureWidth, params.pictureHeight,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002203 HAL_PIXEL_FORMAT_BLOB, maxJpegSize.data.i32[0],
2204 &mCaptureStreamId);
2205 if (res != OK) {
2206 ALOGE("%s: Camera %d: Can't create output stream for capture: "
2207 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2208 return res;
2209 }
2210
2211 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002212 return OK;
2213}
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002214
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002215status_t Camera2Client::updateCaptureRequest(const Parameters &params) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002216 ATRACE_CALL();
2217 status_t res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002218 if (mCaptureRequest.entryCount() == 0) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002219 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_STILL_CAPTURE,
2220 &mCaptureRequest);
2221 if (res != OK) {
2222 ALOGE("%s: Camera %d: Unable to create default still image request:"
2223 " %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2224 return res;
2225 }
2226 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002227
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002228 res = updateRequestCommon(&mCaptureRequest, params);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002229 if (res != OK) {
2230 ALOGE("%s: Camera %d: Unable to update common entries of capture "
2231 "request: %s (%d)", __FUNCTION__, mCameraId,
2232 strerror(-res), res);
2233 return res;
2234 }
2235
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002236 res = mCaptureRequest.update(ANDROID_JPEG_THUMBNAIL_SIZE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002237 params.jpegThumbSize, 2);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002238 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002239 res = mCaptureRequest.update(ANDROID_JPEG_THUMBNAIL_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002240 &params.jpegThumbQuality, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002241 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002242 res = mCaptureRequest.update(ANDROID_JPEG_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002243 &params.jpegQuality, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002244 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002245 res = mCaptureRequest.update(
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002246 ANDROID_JPEG_ORIENTATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002247 &params.jpegRotation, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002248 if (res != OK) return res;
2249
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002250 if (params.gpsEnabled) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002251 res = mCaptureRequest.update(
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002252 ANDROID_JPEG_GPS_COORDINATES,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002253 params.gpsCoordinates, 3);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002254 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002255 res = mCaptureRequest.update(
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002256 ANDROID_JPEG_GPS_TIMESTAMP,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002257 &params.gpsTimestamp, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002258 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002259 res = mCaptureRequest.update(
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002260 ANDROID_JPEG_GPS_PROCESSING_METHOD,
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002261 params.gpsProcessingMethod);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002262 if (res != OK) return res;
2263 } else {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002264 res = mCaptureRequest.erase(ANDROID_JPEG_GPS_COORDINATES);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002265 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002266 res = mCaptureRequest.erase(ANDROID_JPEG_GPS_TIMESTAMP);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002267 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002268 res = mCaptureRequest.erase(ANDROID_JPEG_GPS_PROCESSING_METHOD);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002269 if (res != OK) return res;
2270 }
2271
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002272 return OK;
2273}
2274
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002275status_t Camera2Client::updateRecordingRequest(const Parameters &params) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002276 ATRACE_CALL();
2277 status_t res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002278 if (mRecordingRequest.entryCount() == 0) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002279 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_VIDEO_RECORD,
2280 &mRecordingRequest);
2281 if (res != OK) {
2282 ALOGE("%s: Camera %d: Unable to create default recording request:"
2283 " %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2284 return res;
2285 }
2286 }
2287
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002288 res = updateRequestCommon(&mRecordingRequest, params);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002289 if (res != OK) {
2290 ALOGE("%s: Camera %d: Unable to update common entries of recording "
2291 "request: %s (%d)", __FUNCTION__, mCameraId,
2292 strerror(-res), res);
2293 return res;
2294 }
2295
2296 return OK;
2297}
2298
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002299status_t Camera2Client::updateRecordingStream(const Parameters &params) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002300 status_t res;
2301
2302 if (mRecordingConsumer == 0) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002303 // Create CPU buffer queue endpoint. We need one more buffer here so that we can
2304 // always acquire and free a buffer when the heap is full; otherwise the consumer
2305 // will have buffers in flight we'll never clear out.
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07002306 mRecordingConsumer = new BufferItemConsumer(
2307 GRALLOC_USAGE_HW_VIDEO_ENCODER,
2308 mRecordingHeapCount + 1,
2309 true);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002310 mRecordingConsumer->setFrameAvailableListener(new RecordingWaiter(this));
2311 mRecordingConsumer->setName(String8("Camera2Client::RecordingConsumer"));
2312 mRecordingWindow = new SurfaceTextureClient(
2313 mRecordingConsumer->getProducerInterface());
2314 // Allocate memory later, since we don't know buffer size until receipt
2315 }
2316
2317 if (mRecordingStreamId != NO_STREAM) {
2318 // Check if stream parameters have to change
2319 uint32_t currentWidth, currentHeight;
2320 res = mDevice->getStreamInfo(mRecordingStreamId,
2321 &currentWidth, &currentHeight, 0);
2322 if (res != OK) {
2323 ALOGE("%s: Camera %d: Error querying recording output stream info: "
2324 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2325 return res;
2326 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002327 if (currentWidth != (uint32_t)params.videoWidth ||
2328 currentHeight != (uint32_t)params.videoHeight) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002329 // TODO: Should wait to be sure previous recording has finished
2330 res = mDevice->deleteStream(mRecordingStreamId);
2331 if (res != OK) {
2332 ALOGE("%s: Camera %d: Unable to delete old output stream "
2333 "for recording: %s (%d)", __FUNCTION__, mCameraId,
2334 strerror(-res), res);
2335 return res;
2336 }
2337 mRecordingStreamId = NO_STREAM;
2338 }
2339 }
2340
2341 if (mRecordingStreamId == NO_STREAM) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002342 mRecordingFrameCount = 0;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002343 res = mDevice->createStream(mRecordingWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002344 params.videoWidth, params.videoHeight,
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002345 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0, &mRecordingStreamId);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002346 if (res != OK) {
2347 ALOGE("%s: Camera %d: Can't create output stream for recording: "
2348 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2349 return res;
2350 }
2351 }
2352
2353 return OK;
2354}
2355
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002356status_t Camera2Client::updateRequestCommon(CameraMetadata *request,
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07002357 const Parameters &params) const {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002358 ATRACE_CALL();
2359 status_t res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002360 res = request->update(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
2361 params.previewFpsRange, 2);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002362 if (res != OK) return res;
2363
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002364 uint8_t wbMode = params.autoWhiteBalanceLock ?
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002365 (uint8_t)ANDROID_CONTROL_AWB_LOCKED : params.wbMode;
2366 res = request->update(ANDROID_CONTROL_AWB_MODE,
2367 &wbMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002368 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002369 res = request->update(ANDROID_CONTROL_EFFECT_MODE,
2370 &params.effectMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002371 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002372 res = request->update(ANDROID_CONTROL_AE_ANTIBANDING_MODE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002373 &params.antibandingMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002374 if (res != OK) return res;
2375
2376 uint8_t controlMode =
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002377 (params.sceneMode == ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED) ?
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002378 ANDROID_CONTROL_AUTO : ANDROID_CONTROL_USE_SCENE_MODE;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002379 res = request->update(ANDROID_CONTROL_MODE,
2380 &controlMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002381 if (res != OK) return res;
2382 if (controlMode == ANDROID_CONTROL_USE_SCENE_MODE) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002383 res = request->update(ANDROID_CONTROL_SCENE_MODE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002384 &params.sceneMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002385 if (res != OK) return res;
2386 }
2387
2388 uint8_t flashMode = ANDROID_FLASH_OFF;
2389 uint8_t aeMode;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002390 switch (params.flashMode) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002391 case Parameters::FLASH_MODE_OFF:
2392 aeMode = ANDROID_CONTROL_AE_ON; break;
2393 case Parameters::FLASH_MODE_AUTO:
2394 aeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH; break;
2395 case Parameters::FLASH_MODE_ON:
2396 aeMode = ANDROID_CONTROL_AE_ON_ALWAYS_FLASH; break;
2397 case Parameters::FLASH_MODE_TORCH:
2398 aeMode = ANDROID_CONTROL_AE_ON;
2399 flashMode = ANDROID_FLASH_TORCH;
2400 break;
2401 case Parameters::FLASH_MODE_RED_EYE:
2402 aeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE; break;
2403 default:
2404 ALOGE("%s: Camera %d: Unknown flash mode %d", __FUNCTION__,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002405 mCameraId, params.flashMode);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002406 return BAD_VALUE;
2407 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002408 if (params.autoExposureLock) aeMode = ANDROID_CONTROL_AE_LOCKED;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002409
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002410 res = request->update(ANDROID_FLASH_MODE,
2411 &flashMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002412 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002413 res = request->update(ANDROID_CONTROL_AE_MODE,
2414 &aeMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002415 if (res != OK) return res;
2416
2417 float focusDistance = 0; // infinity focus in diopters
2418 uint8_t focusMode;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002419 switch (params.focusMode) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002420 case Parameters::FOCUS_MODE_AUTO:
2421 case Parameters::FOCUS_MODE_MACRO:
2422 case Parameters::FOCUS_MODE_CONTINUOUS_VIDEO:
2423 case Parameters::FOCUS_MODE_CONTINUOUS_PICTURE:
2424 case Parameters::FOCUS_MODE_EDOF:
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002425 focusMode = params.focusMode;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002426 break;
2427 case Parameters::FOCUS_MODE_INFINITY:
2428 case Parameters::FOCUS_MODE_FIXED:
2429 focusMode = ANDROID_CONTROL_AF_OFF;
2430 break;
2431 default:
2432 ALOGE("%s: Camera %d: Unknown focus mode %d", __FUNCTION__,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002433 mCameraId, params.focusMode);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002434 return BAD_VALUE;
2435 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002436 res = request->update(ANDROID_LENS_FOCUS_DISTANCE,
2437 &focusDistance, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002438 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002439 res = request->update(ANDROID_CONTROL_AF_MODE,
2440 &focusMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002441 if (res != OK) return res;
2442
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002443 size_t focusingAreasSize = params.focusingAreas.size() * 5;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002444 int32_t *focusingAreas = new int32_t[focusingAreasSize];
2445 for (size_t i = 0; i < focusingAreasSize; i += 5) {
Eino-Ville Talvalaf17b6cf2012-08-25 17:12:18 -07002446 if (params.focusingAreas[i].weight != 0) {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07002447 focusingAreas[i + 0] =
2448 params.normalizedXToArray(params.focusingAreas[i].left);
2449 focusingAreas[i + 1] =
2450 params.normalizedYToArray(params.focusingAreas[i].top);
2451 focusingAreas[i + 2] =
2452 params.normalizedXToArray(params.focusingAreas[i].right);
2453 focusingAreas[i + 3] =
2454 params.normalizedYToArray(params.focusingAreas[i].bottom);
Eino-Ville Talvalaf17b6cf2012-08-25 17:12:18 -07002455 } else {
2456 focusingAreas[i + 0] = 0;
2457 focusingAreas[i + 1] = 0;
2458 focusingAreas[i + 2] = 0;
2459 focusingAreas[i + 3] = 0;
2460 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002461 focusingAreas[i + 4] = params.focusingAreas[i].weight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002462 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002463 res = request->update(ANDROID_CONTROL_AF_REGIONS,
2464 focusingAreas,focusingAreasSize);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002465 if (res != OK) return res;
2466 delete[] focusingAreas;
2467
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002468 res = request->update(ANDROID_CONTROL_AE_EXP_COMPENSATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002469 &params.exposureCompensation, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002470 if (res != OK) return res;
2471
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002472 size_t meteringAreasSize = params.meteringAreas.size() * 5;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002473 int32_t *meteringAreas = new int32_t[meteringAreasSize];
2474 for (size_t i = 0; i < meteringAreasSize; i += 5) {
Eino-Ville Talvalaf17b6cf2012-08-25 17:12:18 -07002475 if (params.meteringAreas[i].weight != 0) {
2476 meteringAreas[i + 0] =
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07002477 params.normalizedXToArray(params.meteringAreas[i].left);
Eino-Ville Talvalaf17b6cf2012-08-25 17:12:18 -07002478 meteringAreas[i + 1] =
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07002479 params.normalizedYToArray(params.meteringAreas[i].top);
Eino-Ville Talvalaf17b6cf2012-08-25 17:12:18 -07002480 meteringAreas[i + 2] =
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07002481 params.normalizedXToArray(params.meteringAreas[i].right);
Eino-Ville Talvalaf17b6cf2012-08-25 17:12:18 -07002482 meteringAreas[i + 3] =
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07002483 params.normalizedYToArray(params.meteringAreas[i].bottom);
Eino-Ville Talvalaf17b6cf2012-08-25 17:12:18 -07002484 } else {
2485 meteringAreas[i + 0] = 0;
2486 meteringAreas[i + 1] = 0;
2487 meteringAreas[i + 2] = 0;
2488 meteringAreas[i + 3] = 0;
2489 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002490 meteringAreas[i + 4] = params.meteringAreas[i].weight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002491 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002492 res = request->update(ANDROID_CONTROL_AE_REGIONS,
2493 meteringAreas, meteringAreasSize);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002494 if (res != OK) return res;
2495
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002496 res = request->update(ANDROID_CONTROL_AWB_REGIONS,
2497 meteringAreas, meteringAreasSize);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002498 if (res != OK) return res;
2499 delete[] meteringAreas;
2500
2501 // Need to convert zoom index into a crop rectangle. The rectangle is
2502 // chosen to maximize its area on the sensor
2503
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002504 camera_metadata_ro_entry_t maxDigitalZoom =
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07002505 mParameters.staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002506 float zoomIncrement = (maxDigitalZoom.data.f[0] - 1) /
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07002507 (params.NUM_ZOOM_STEPS-1);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002508 float zoomRatio = 1 + zoomIncrement * params.zoom;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002509
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002510 float zoomLeft, zoomTop, zoomWidth, zoomHeight;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002511 if (params.previewWidth >= params.previewHeight) {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07002512 zoomWidth = params.fastInfo.arrayWidth / zoomRatio;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002513 zoomHeight = zoomWidth *
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002514 params.previewHeight / params.previewWidth;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002515 } else {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07002516 zoomHeight = params.fastInfo.arrayHeight / zoomRatio;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002517 zoomWidth = zoomHeight *
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002518 params.previewWidth / params.previewHeight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002519 }
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07002520 zoomLeft = (params.fastInfo.arrayWidth - zoomWidth) / 2;
2521 zoomTop = (params.fastInfo.arrayHeight - zoomHeight) / 2;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002522
2523 int32_t cropRegion[3] = { zoomLeft, zoomTop, zoomWidth };
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002524 res = request->update(ANDROID_SCALER_CROP_REGION,
2525 cropRegion, 3);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002526 if (res != OK) return res;
2527
2528 // TODO: Decide how to map recordingHint, or whether just to ignore it
2529
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002530 uint8_t vstabMode = params.videoStabilization ?
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002531 ANDROID_CONTROL_VIDEO_STABILIZATION_ON :
2532 ANDROID_CONTROL_VIDEO_STABILIZATION_OFF;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002533 res = request->update(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002534 &vstabMode, 1);
2535 if (res != OK) return res;
2536
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002537 uint8_t faceDetectMode = params.enableFaceDetect ?
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07002538 params.fastInfo.bestFaceDetectMode :
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002539 (uint8_t)ANDROID_STATS_FACE_DETECTION_OFF;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002540 res = request->update(ANDROID_STATS_FACE_DETECT_MODE,
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002541 &faceDetectMode, 1);
2542 if (res != OK) return res;
2543
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002544 return OK;
2545}
2546
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002547size_t Camera2Client::calculateBufferSize(int width, int height,
2548 int format, int stride) {
2549 switch (format) {
2550 case HAL_PIXEL_FORMAT_YCbCr_422_SP: // NV16
2551 return width * height * 2;
2552 case HAL_PIXEL_FORMAT_YCrCb_420_SP: // NV21
2553 return width * height * 3 / 2;
2554 case HAL_PIXEL_FORMAT_YCbCr_422_I: // YUY2
2555 return width * height * 2;
2556 case HAL_PIXEL_FORMAT_YV12: { // YV12
2557 size_t ySize = stride * height;
Eino-Ville Talvalaf17b6cf2012-08-25 17:12:18 -07002558 size_t uvStride = (stride / 2 + 0xF) & ~0xF;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002559 size_t uvSize = uvStride * height / 2;
2560 return ySize + uvSize * 2;
2561 }
2562 case HAL_PIXEL_FORMAT_RGB_565:
2563 return width * height * 2;
2564 case HAL_PIXEL_FORMAT_RGBA_8888:
2565 return width * height * 4;
2566 case HAL_PIXEL_FORMAT_RAW_SENSOR:
2567 return width * height * 2;
2568 default:
2569 ALOGE("%s: Unknown preview format: %x",
2570 __FUNCTION__, format);
2571 return 0;
2572 }
2573}
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002574
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07002575} // namespace android