blob: 4edb49f3716f21326f089c33aa5674d4bb6fc791 [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
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700396 mCameraClient = client;
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -0700397 mSharedCameraClient = client;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700398
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()) {
436 mClientPid = 0;
437 mCameraClient.clear();
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -0700438 mSharedCameraClient.clear();
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700439 return OK;
440 }
441
442 ALOGE("%s: Camera %d: Unlock call from pid %d; currently locked to pid %d",
443 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
444 return EBUSY;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700445}
446
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700447status_t Camera2Client::setPreviewDisplay(
448 const sp<Surface>& surface) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700449 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700450 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700451 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700452 status_t res;
453 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700454
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700455 sp<IBinder> binder;
456 sp<ANativeWindow> window;
457 if (surface != 0) {
458 binder = surface->asBinder();
459 window = surface;
460 }
461
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700462 return setPreviewWindowL(binder,window);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700463}
464
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700465status_t Camera2Client::setPreviewTexture(
466 const sp<ISurfaceTexture>& surfaceTexture) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700467 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700468 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700469 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700470 status_t res;
471 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700472
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700473 sp<IBinder> binder;
474 sp<ANativeWindow> window;
475 if (surfaceTexture != 0) {
476 binder = surfaceTexture->asBinder();
477 window = new SurfaceTextureClient(surfaceTexture);
478 }
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700479 return setPreviewWindowL(binder, window);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700480}
481
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700482status_t Camera2Client::setPreviewWindowL(const sp<IBinder>& binder,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700483 sp<ANativeWindow> window) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700484 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700485 status_t res;
486
487 if (binder == mPreviewSurface) {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700488 ALOGV("%s: Camera %d: New window is same as old window",
489 __FUNCTION__, mCameraId);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700490 return NO_ERROR;
491 }
492
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700493 SharedParameters::Lock l(mParameters);
494 switch (l.mParameters.state) {
495 case Parameters::DISCONNECTED:
496 case Parameters::RECORD:
497 case Parameters::STILL_CAPTURE:
498 case Parameters::VIDEO_SNAPSHOT:
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700499 ALOGE("%s: Camera %d: Cannot set preview display while in state %s",
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700500 __FUNCTION__, mCameraId,
501 Parameters::getStateName(l.mParameters.state));
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700502 return INVALID_OPERATION;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700503 case Parameters::STOPPED:
504 case Parameters::WAITING_FOR_PREVIEW_WINDOW:
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700505 // OK
506 break;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700507 case Parameters::PREVIEW:
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700508 // Already running preview - need to stop and create a new stream
509 // TODO: Optimize this so that we don't wait for old stream to drain
510 // before spinning up new stream
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700511 mDevice->clearStreamingRequest();
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700512 l.mParameters.state = Parameters::WAITING_FOR_PREVIEW_WINDOW;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700513 break;
514 }
515
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700516 if (mPreviewStreamId != NO_STREAM) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700517 res = mDevice->waitUntilDrained();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700518 if (res != OK) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700519 ALOGE("%s: Error waiting for preview to drain: %s (%d)",
520 __FUNCTION__, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700521 return res;
522 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700523 res = mDevice->deleteStream(mPreviewStreamId);
524 if (res != OK) {
525 ALOGE("%s: Unable to delete old preview stream: %s (%d)",
526 __FUNCTION__, strerror(-res), res);
527 return res;
528 }
529 mPreviewStreamId = NO_STREAM;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700530 }
531
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700532 mPreviewSurface = binder;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700533 mPreviewWindow = window;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700534
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700535 if (l.mParameters.state == Parameters::WAITING_FOR_PREVIEW_WINDOW) {
536 return startPreviewL(l.mParameters, false);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700537 }
538
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700539 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700540}
541
542void Camera2Client::setPreviewCallbackFlag(int flag) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700543 ATRACE_CALL();
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700544 ALOGV("%s: Camera %d: Flag 0x%x", __FUNCTION__, mCameraId, flag);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700545 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700546 status_t res;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700547 if ( checkPid(__FUNCTION__) != OK) return;
548
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700549 SharedParameters::Lock l(mParameters);
550 setPreviewCallbackFlagL(l.mParameters, flag);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700551}
552
553void Camera2Client::setPreviewCallbackFlagL(Parameters &params, int flag) {
554 status_t res = OK;
555 if (flag & CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) {
556 ALOGV("%s: setting oneshot", __FUNCTION__);
557 params.previewCallbackOneShot = true;
558 }
559 if (params.previewCallbackFlags != (uint32_t)flag) {
560 params.previewCallbackFlags = flag;
561 switch(params.state) {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700562 case Parameters::PREVIEW:
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700563 res = startPreviewL(params, true);
564 break;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700565 case Parameters::RECORD:
566 case Parameters::VIDEO_SNAPSHOT:
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700567 res = startRecordingL(params, true);
568 break;
569 default:
570 break;
571 }
572 if (res != OK) {
573 ALOGE("%s: Camera %d: Unable to refresh request in state %s",
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700574 __FUNCTION__, mCameraId,
575 Parameters::getStateName(params.state));
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700576 }
577 }
578
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700579}
580
581status_t Camera2Client::startPreview() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700582 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700583 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700584 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700585 status_t res;
586 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700587 SharedParameters::Lock l(mParameters);
588 return startPreviewL(l.mParameters, false);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700589}
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700590
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700591status_t Camera2Client::startPreviewL(Parameters &params, bool restart) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700592 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700593 status_t res;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700594 if (params.state >= Parameters::PREVIEW && !restart) {
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700595 ALOGE("%s: Can't start preview in state %s",
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700596 __FUNCTION__,
597 Parameters::getStateName(params.state));
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700598 return INVALID_OPERATION;
599 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700600
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700601 if (mPreviewWindow == 0) {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700602 params.state = Parameters::WAITING_FOR_PREVIEW_WINDOW;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700603 return OK;
604 }
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700605 params.state = Parameters::STOPPED;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700606
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700607 res = updatePreviewStream(params);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700608 if (res != OK) {
609 ALOGE("%s: Camera %d: Unable to update preview stream: %s (%d)",
610 __FUNCTION__, mCameraId, strerror(-res), res);
611 return res;
612 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700613 bool callbacksEnabled = params.previewCallbackFlags &
614 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK;
615 if (callbacksEnabled) {
616 res = updateCallbackStream(params);
617 if (res != OK) {
618 ALOGE("%s: Camera %d: Unable to update callback stream: %s (%d)",
619 __FUNCTION__, mCameraId, strerror(-res), res);
620 return res;
621 }
622 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700623
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700624 if (mPreviewRequest.entryCount() == 0) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700625 res = updatePreviewRequest(params);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700626 if (res != OK) {
627 ALOGE("%s: Camera %d: Unable to create preview request: %s (%d)",
628 __FUNCTION__, mCameraId, strerror(-res), res);
629 return res;
630 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700631 }
632
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700633 if (callbacksEnabled) {
634 uint8_t outputStreams[2] =
635 { mPreviewStreamId, mCallbackStreamId };
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700636 res = mPreviewRequest.update(
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700637 ANDROID_REQUEST_OUTPUT_STREAMS,
638 outputStreams, 2);
639 } else {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700640 uint8_t outputStreams[1] = { mPreviewStreamId };
641 res = mPreviewRequest.update(
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700642 ANDROID_REQUEST_OUTPUT_STREAMS,
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700643 outputStreams, 1);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700644 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700645 if (res != OK) {
646 ALOGE("%s: Camera %d: Unable to set up preview request: %s (%d)",
647 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700648 return res;
649 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700650 res = mPreviewRequest.sort();
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700651 if (res != OK) {
652 ALOGE("%s: Camera %d: Error sorting preview request: %s (%d)",
653 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700654 return res;
655 }
656
657 res = mDevice->setStreamingRequest(mPreviewRequest);
658 if (res != OK) {
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700659 ALOGE("%s: Camera %d: Unable to set preview request to start preview: "
660 "%s (%d)",
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700661 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700662 return res;
663 }
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700664 params.state = Parameters::PREVIEW;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700665
666 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700667}
668
669void Camera2Client::stopPreview() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700670 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700671 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700672 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700673 status_t res;
674 if ( (res = checkPid(__FUNCTION__) ) != OK) return;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700675 stopPreviewL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700676}
677
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700678void Camera2Client::stopPreviewL() {
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700679 ATRACE_CALL();
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700680 Parameters::State state;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700681 {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700682 SharedParameters::Lock l(mParameters);
683 state = l.mParameters.state;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700684 }
685
686 switch (state) {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700687 case Parameters::DISCONNECTED:
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700688 ALOGE("%s: Camera %d: Call before initialized",
689 __FUNCTION__, mCameraId);
690 break;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700691 case Parameters::STOPPED:
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700692 break;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700693 case Parameters::STILL_CAPTURE:
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700694 ALOGE("%s: Camera %d: Cannot stop preview during still capture.",
695 __FUNCTION__, mCameraId);
696 break;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700697 case Parameters::RECORD:
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700698 // no break - identical to preview
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700699 case Parameters::PREVIEW:
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700700 mDevice->clearStreamingRequest();
Eino-Ville Talvala22671062012-07-20 18:30:37 -0700701 mDevice->waitUntilDrained();
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700702 // no break
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700703 case Parameters::WAITING_FOR_PREVIEW_WINDOW: {
704 SharedParameters::Lock l(mParameters);
705 l.mParameters.state = Parameters::STOPPED;
706 commandStopFaceDetectionL(l.mParameters);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700707 break;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700708 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700709 default:
710 ALOGE("%s: Camera %d: Unknown state %d", __FUNCTION__, mCameraId,
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700711 state);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700712 }
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700713}
714
715bool Camera2Client::previewEnabled() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700716 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700717 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700718 status_t res;
719 if ( (res = checkPid(__FUNCTION__) ) != OK) return false;
720
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700721 SharedParameters::Lock l(mParameters);
722 return l.mParameters.state == Parameters::PREVIEW;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700723}
724
725status_t Camera2Client::storeMetaDataInBuffers(bool enabled) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700726 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700727 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700728 status_t res;
729 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
730
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700731 SharedParameters::Lock l(mParameters);
732 switch (l.mParameters.state) {
733 case Parameters::RECORD:
734 case Parameters::VIDEO_SNAPSHOT:
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700735 ALOGE("%s: Camera %d: Can't be called in state %s",
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700736 __FUNCTION__, mCameraId,
737 Parameters::getStateName(l.mParameters.state));
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700738 return INVALID_OPERATION;
739 default:
740 // OK
741 break;
742 }
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700743
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700744 l.mParameters.storeMetadataInBuffers = enabled;
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700745
746 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700747}
748
749status_t Camera2Client::startRecording() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700750 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700751 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700752 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700753 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700754 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700755 SharedParameters::Lock l(mParameters);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700756
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700757 return startRecordingL(l.mParameters, false);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700758}
759
760status_t Camera2Client::startRecordingL(Parameters &params, bool restart) {
761 status_t res;
762 switch (params.state) {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700763 case Parameters::STOPPED:
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700764 res = startPreviewL(params, false);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700765 if (res != OK) return res;
766 break;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700767 case Parameters::PREVIEW:
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700768 // Ready to go
769 break;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700770 case Parameters::RECORD:
771 case Parameters::VIDEO_SNAPSHOT:
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700772 // OK to call this when recording is already on, just skip unless
773 // we're looking to restart
774 if (!restart) return OK;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700775 break;
776 default:
777 ALOGE("%s: Camera %d: Can't start recording in state %s",
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700778 __FUNCTION__, mCameraId,
779 Parameters::getStateName(params.state));
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700780 return INVALID_OPERATION;
781 };
782
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700783 if (!params.storeMetadataInBuffers) {
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700784 ALOGE("%s: Camera %d: Recording only supported in metadata mode, but "
785 "non-metadata recording mode requested!", __FUNCTION__,
786 mCameraId);
787 return INVALID_OPERATION;
788 }
789
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700790 res = updateRecordingStream(params);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700791 if (res != OK) {
792 ALOGE("%s: Camera %d: Unable to update recording stream: %s (%d)",
793 __FUNCTION__, mCameraId, strerror(-res), res);
794 return res;
795 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700796 bool callbacksEnabled = params.previewCallbackFlags &
797 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK;
798 if (callbacksEnabled) {
799 res = updateCallbackStream(params);
800 if (res != OK) {
801 ALOGE("%s: Camera %d: Unable to update callback stream: %s (%d)",
802 __FUNCTION__, mCameraId, strerror(-res), res);
803 return res;
804 }
805 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700806
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700807 if (mRecordingRequest.entryCount() == 0) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700808 res = updateRecordingRequest(params);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700809 if (res != OK) {
810 ALOGE("%s: Camera %d: Unable to create recording request: %s (%d)",
811 __FUNCTION__, mCameraId, strerror(-res), res);
812 return res;
813 }
814 }
815
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700816 if (callbacksEnabled) {
817 uint8_t outputStreams[3] =
818 { mPreviewStreamId, mRecordingStreamId, mCallbackStreamId };
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700819 res = mRecordingRequest.update(
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700820 ANDROID_REQUEST_OUTPUT_STREAMS,
821 outputStreams, 3);
822 } else {
823 uint8_t outputStreams[2] = { mPreviewStreamId, mRecordingStreamId };
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700824 res = mRecordingRequest.update(
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700825 ANDROID_REQUEST_OUTPUT_STREAMS,
826 outputStreams, 2);
827 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700828 if (res != OK) {
829 ALOGE("%s: Camera %d: Unable to set up recording request: %s (%d)",
830 __FUNCTION__, mCameraId, strerror(-res), res);
831 return res;
832 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700833 res = mRecordingRequest.sort();
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700834 if (res != OK) {
835 ALOGE("%s: Camera %d: Error sorting recording request: %s (%d)",
836 __FUNCTION__, mCameraId, strerror(-res), res);
837 return res;
838 }
839
840 res = mDevice->setStreamingRequest(mRecordingRequest);
841 if (res != OK) {
842 ALOGE("%s: Camera %d: Unable to set recording request to start "
843 "recording: %s (%d)", __FUNCTION__, mCameraId,
844 strerror(-res), res);
845 return res;
846 }
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700847 if (params.state < Parameters::RECORD) {
848 params.state = Parameters::RECORD;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700849 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700850
851 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700852}
853
854void Camera2Client::stopRecording() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700855 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700856 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700857 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700858 SharedParameters::Lock l(mParameters);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700859
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700860 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700861 if ( (res = checkPid(__FUNCTION__) ) != OK) return;
862
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700863 switch (l.mParameters.state) {
864 case Parameters::RECORD:
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700865 // OK to stop
866 break;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700867 case Parameters::STOPPED:
868 case Parameters::PREVIEW:
869 case Parameters::STILL_CAPTURE:
870 case Parameters::VIDEO_SNAPSHOT:
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700871 default:
872 ALOGE("%s: Camera %d: Can't stop recording in state %s",
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700873 __FUNCTION__, mCameraId,
874 Parameters::getStateName(l.mParameters.state));
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700875 return;
876 };
877
878 // Back to preview. Since record can only be reached through preview,
879 // all preview stream setup should be up to date.
880 res = mDevice->setStreamingRequest(mPreviewRequest);
881 if (res != OK) {
882 ALOGE("%s: Camera %d: Unable to switch back to preview request: "
883 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
884 return;
885 }
886
887 // TODO: Should recording heap be freed? Can't do it yet since requests
888 // could still be in flight.
889
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700890 l.mParameters.state = Parameters::PREVIEW;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700891}
892
893bool Camera2Client::recordingEnabled() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700894 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700895 Mutex::Autolock icl(mICameraLock);
James Dong8da4cd72012-08-04 19:58:07 -0700896
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700897 if ( checkPid(__FUNCTION__) != OK) return false;
898
James Dong8da4cd72012-08-04 19:58:07 -0700899 return recordingEnabledL();
900}
901
902bool Camera2Client::recordingEnabledL() {
903 ATRACE_CALL();
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700904 SharedParameters::Lock l(mParameters);
James Dong8da4cd72012-08-04 19:58:07 -0700905
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700906 return (l.mParameters.state == Parameters::RECORD
907 || l.mParameters.state == Parameters::VIDEO_SNAPSHOT);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700908}
909
910void Camera2Client::releaseRecordingFrame(const sp<IMemory>& mem) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700911 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700912 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700913 status_t res;
914 if ( checkPid(__FUNCTION__) != OK) return;
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -0700915
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700916 SharedParameters::Lock l(mParameters);
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -0700917
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700918 // Make sure this is for the current heap
919 ssize_t offset;
920 size_t size;
921 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
922 if (heap->getHeapID() != mRecordingHeap->mHeap->getHeapID()) {
923 ALOGW("%s: Camera %d: Mismatched heap ID, ignoring release "
924 "(got %x, expected %x)", __FUNCTION__, mCameraId,
925 heap->getHeapID(), mRecordingHeap->mHeap->getHeapID());
926 return;
927 }
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700928 uint8_t *data = (uint8_t*)heap->getBase() + offset;
929 uint32_t type = *(uint32_t*)data;
930 if (type != kMetadataBufferTypeGrallocSource) {
931 ALOGE("%s: Camera %d: Recording frame type invalid (got %x, expected %x)",
932 __FUNCTION__, mCameraId, type, kMetadataBufferTypeGrallocSource);
933 return;
934 }
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -0700935
936 // Release the buffer back to the recording queue
937
938 buffer_handle_t imgHandle = *(buffer_handle_t*)(data + 4);
939
940 size_t itemIndex;
941 for (itemIndex = 0; itemIndex < mRecordingBuffers.size(); itemIndex++) {
942 const BufferItemConsumer::BufferItem item = mRecordingBuffers[itemIndex];
943 if (item.mBuf != BufferItemConsumer::INVALID_BUFFER_SLOT &&
944 item.mGraphicBuffer->handle == imgHandle) {
945 break;
946 }
947 }
948 if (itemIndex == mRecordingBuffers.size()) {
949 ALOGE("%s: Camera %d: Can't find buffer_handle_t %p in list of "
950 "outstanding buffers", __FUNCTION__, mCameraId, imgHandle);
951 return;
952 }
953
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700954 ALOGV("%s: Camera %d: Freeing buffer_handle_t %p", __FUNCTION__, mCameraId,
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -0700955 imgHandle);
956
957 res = mRecordingConsumer->releaseBuffer(mRecordingBuffers[itemIndex]);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700958 if (res != OK) {
959 ALOGE("%s: Camera %d: Unable to free recording frame (buffer_handle_t: %p):"
960 "%s (%d)",
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -0700961 __FUNCTION__, mCameraId, imgHandle, strerror(-res), res);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700962 return;
963 }
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -0700964 mRecordingBuffers.replaceAt(itemIndex);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700965
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700966 mRecordingHeapFree++;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700967}
968
969status_t Camera2Client::autoFocus() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700970 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700971 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700972 status_t res;
973 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
974
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700975 int triggerId;
976 {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700977 SharedParameters::Lock l(mParameters);
978 l.mParameters.currentAfTriggerId = ++l.mParameters.afTriggerCounter;
979 triggerId = l.mParameters.currentAfTriggerId;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700980 }
981
982 mDevice->triggerAutofocus(triggerId);
983
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700984 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700985}
986
987status_t Camera2Client::cancelAutoFocus() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700988 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700989 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700990 status_t res;
991 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
992
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700993 int triggerId;
994 {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700995 SharedParameters::Lock l(mParameters);
996 triggerId = ++l.mParameters.afTriggerCounter;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700997 }
998
999 mDevice->triggerCancelAutofocus(triggerId);
1000
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001001 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001002}
1003
1004status_t Camera2Client::takePicture(int msgType) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001005 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001006 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001007 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001008 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001009
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001010 SharedParameters::Lock l(mParameters);
1011 switch (l.mParameters.state) {
1012 case Parameters::DISCONNECTED:
1013 case Parameters::STOPPED:
1014 case Parameters::WAITING_FOR_PREVIEW_WINDOW:
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001015 ALOGE("%s: Camera %d: Cannot take picture without preview enabled",
1016 __FUNCTION__, mCameraId);
1017 return INVALID_OPERATION;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001018 case Parameters::PREVIEW:
1019 case Parameters::RECORD:
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001020 // Good to go for takePicture
1021 break;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001022 case Parameters::STILL_CAPTURE:
1023 case Parameters::VIDEO_SNAPSHOT:
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001024 ALOGE("%s: Camera %d: Already taking a picture",
1025 __FUNCTION__, mCameraId);
1026 return INVALID_OPERATION;
1027 }
1028
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001029 ALOGV("%s: Camera %d: Starting picture capture", __FUNCTION__, mCameraId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001030
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001031 res = updateCaptureStream(l.mParameters);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001032 if (res != OK) {
1033 ALOGE("%s: Camera %d: Can't set up still image stream: %s (%d)",
1034 __FUNCTION__, mCameraId, strerror(-res), res);
1035 return res;
1036 }
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001037
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001038 if (mCaptureRequest.entryCount() == 0) {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001039 res = updateCaptureRequest(l.mParameters);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -07001040 if (res != OK) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001041 ALOGE("%s: Camera %d: Can't create still image capture request: "
1042 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -07001043 return res;
1044 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001045 }
1046
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001047 bool callbacksEnabled = l.mParameters.previewCallbackFlags &
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001048 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001049 bool recordingEnabled = (l.mParameters.state == Parameters::RECORD);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001050
1051 int streamSwitch = (callbacksEnabled ? 0x2 : 0x0) +
1052 (recordingEnabled ? 0x1 : 0x0);
1053 switch ( streamSwitch ) {
1054 case 0: { // No recording, callbacks
1055 uint8_t streamIds[2] = { mPreviewStreamId, mCaptureStreamId };
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001056 res = mCaptureRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS,
1057 streamIds, 2);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001058 break;
1059 }
1060 case 1: { // Recording
1061 uint8_t streamIds[3] = { mPreviewStreamId, mRecordingStreamId,
1062 mCaptureStreamId };
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001063 res = mCaptureRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS,
1064 streamIds, 3);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001065 break;
1066 }
1067 case 2: { // Callbacks
1068 uint8_t streamIds[3] = { mPreviewStreamId, mCallbackStreamId,
1069 mCaptureStreamId };
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001070 res = mCaptureRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS,
1071 streamIds, 3);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001072 break;
1073 }
1074 case 3: { // Both
1075 uint8_t streamIds[4] = { mPreviewStreamId, mCallbackStreamId,
1076 mRecordingStreamId, mCaptureStreamId };
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001077 res = mCaptureRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS,
1078 streamIds, 4);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001079 break;
1080 }
1081 };
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001082 if (res != OK) {
1083 ALOGE("%s: Camera %d: Unable to set up still image capture request: "
1084 "%s (%d)",
1085 __FUNCTION__, mCameraId, strerror(-res), res);
1086 return res;
1087 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001088 res = mCaptureRequest.sort();
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001089 if (res != OK) {
1090 ALOGE("%s: Camera %d: Unable to sort capture request: %s (%d)",
1091 __FUNCTION__, mCameraId, strerror(-res), res);
1092 return res;
1093 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001094
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001095 CameraMetadata captureCopy = mCaptureRequest;
1096 if (captureCopy.entryCount() == 0) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001097 ALOGE("%s: Camera %d: Unable to copy capture request for HAL device",
1098 __FUNCTION__, mCameraId);
1099 return NO_MEMORY;
1100 }
1101
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001102 if (l.mParameters.state == Parameters::PREVIEW) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001103 res = mDevice->clearStreamingRequest();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001104 if (res != OK) {
1105 ALOGE("%s: Camera %d: Unable to stop preview for still capture: "
1106 "%s (%d)",
1107 __FUNCTION__, mCameraId, strerror(-res), res);
1108 return res;
1109 }
1110 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001111 // TODO: Capture should be atomic with setStreamingRequest here
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001112 res = mDevice->capture(captureCopy);
1113 if (res != OK) {
1114 ALOGE("%s: Camera %d: Unable to submit still image capture request: "
1115 "%s (%d)",
1116 __FUNCTION__, mCameraId, strerror(-res), res);
1117 return res;
1118 }
1119
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001120 switch (l.mParameters.state) {
1121 case Parameters::PREVIEW:
1122 l.mParameters.state = Parameters::STILL_CAPTURE;
1123 res = commandStopFaceDetectionL(l.mParameters);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001124 if (res != OK) {
1125 ALOGE("%s: Camera %d: Unable to stop face detection for still capture",
1126 __FUNCTION__, mCameraId);
1127 return res;
1128 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001129 break;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001130 case Parameters::RECORD:
1131 l.mParameters.state = Parameters::VIDEO_SNAPSHOT;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001132 break;
1133 default:
1134 ALOGE("%s: Camera %d: Unknown state for still capture!",
1135 __FUNCTION__, mCameraId);
1136 return INVALID_OPERATION;
1137 }
1138
1139 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001140}
1141
1142status_t Camera2Client::setParameters(const String8& params) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001143 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -07001144 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001145 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001146 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001147 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
1148
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001149 SharedParameters::Lock l(mParameters);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001150
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001151 res = l.mParameters.set(params);
1152 if (res != OK) return res;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001153
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001154 res = updateRequests(l.mParameters);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001155
1156 return res;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001157}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001158
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001159String8 Camera2Client::getParameters() const {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001160 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001161 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001162 if ( checkPid(__FUNCTION__) != OK) return String8();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001163
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001164 SharedParameters::ReadLock l(mParameters);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001165
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001166 // TODO: Deal with focus distances
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001167 return l.mParameters.paramsFlattened;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001168}
1169
1170status_t Camera2Client::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001171 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001172 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001173 status_t res;
1174 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001175
1176 ALOGV("%s: Camera %d: Command %d (%d, %d)", __FUNCTION__, mCameraId,
1177 cmd, arg1, arg2);
1178
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001179 switch (cmd) {
1180 case CAMERA_CMD_START_SMOOTH_ZOOM:
1181 return commandStartSmoothZoomL();
1182 case CAMERA_CMD_STOP_SMOOTH_ZOOM:
1183 return commandStopSmoothZoomL();
1184 case CAMERA_CMD_SET_DISPLAY_ORIENTATION:
1185 return commandSetDisplayOrientationL(arg1);
1186 case CAMERA_CMD_ENABLE_SHUTTER_SOUND:
1187 return commandEnableShutterSoundL(arg1 == 1);
1188 case CAMERA_CMD_PLAY_RECORDING_SOUND:
1189 return commandPlayRecordingSoundL();
1190 case CAMERA_CMD_START_FACE_DETECTION:
1191 return commandStartFaceDetectionL(arg1);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001192 case CAMERA_CMD_STOP_FACE_DETECTION: {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001193 SharedParameters::Lock l(mParameters);
1194 return commandStopFaceDetectionL(l.mParameters);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001195 }
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001196 case CAMERA_CMD_ENABLE_FOCUS_MOVE_MSG:
1197 return commandEnableFocusMoveMsgL(arg1 == 1);
1198 case CAMERA_CMD_PING:
1199 return commandPingL();
1200 case CAMERA_CMD_SET_VIDEO_BUFFER_COUNT:
1201 return commandSetVideoBufferCountL(arg1);
1202 default:
1203 ALOGE("%s: Unknown command %d (arguments %d, %d)",
1204 __FUNCTION__, cmd, arg1, arg2);
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001205 return BAD_VALUE;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001206 }
1207}
James Dong983cf232012-08-01 16:39:55 -07001208
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001209status_t Camera2Client::commandStartSmoothZoomL() {
1210 ALOGE("%s: Unimplemented!", __FUNCTION__);
1211 return OK;
1212}
James Dong983cf232012-08-01 16:39:55 -07001213
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001214status_t Camera2Client::commandStopSmoothZoomL() {
1215 ALOGE("%s: Unimplemented!", __FUNCTION__);
1216 return OK;
1217}
James Dong983cf232012-08-01 16:39:55 -07001218
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001219status_t Camera2Client::commandSetDisplayOrientationL(int degrees) {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001220 int transform = Parameters::degToTransform(degrees,
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001221 mCameraFacing == CAMERA_FACING_FRONT);
1222 if (transform == -1) {
1223 ALOGE("%s: Camera %d: Error setting %d as display orientation value",
1224 __FUNCTION__, mCameraId, degrees);
1225 return BAD_VALUE;
1226 }
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001227 SharedParameters::Lock l(mParameters);
1228 if (transform != l.mParameters.previewTransform &&
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001229 mPreviewStreamId != NO_STREAM) {
1230 mDevice->setStreamTransform(mPreviewStreamId, transform);
1231 }
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001232 l.mParameters.previewTransform = transform;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001233 return OK;
1234}
1235
1236status_t Camera2Client::commandEnableShutterSoundL(bool enable) {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001237 SharedParameters::Lock l(mParameters);
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001238 if (enable) {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001239 l.mParameters.playShutterSound = true;
James Dong983cf232012-08-01 16:39:55 -07001240 return OK;
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001241 }
1242
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001243 // Disabling shutter sound may not be allowed. In that case only
1244 // allow the mediaserver process to disable the sound.
1245 char value[PROPERTY_VALUE_MAX];
1246 property_get("ro.camera.sound.forced", value, "0");
1247 if (strncmp(value, "0", 2) != 0) {
1248 // Disabling shutter sound is not allowed. Deny if the current
1249 // process is not mediaserver.
1250 if (getCallingPid() != getpid()) {
1251 ALOGE("Failed to disable shutter sound. Permission denied (pid %d)",
1252 getCallingPid());
1253 return PERMISSION_DENIED;
1254 }
1255 }
1256
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001257 l.mParameters.playShutterSound = false;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001258 return OK;
1259}
1260
1261status_t Camera2Client::commandPlayRecordingSoundL() {
1262 mCameraService->playSound(CameraService::SOUND_RECORDING);
1263 return OK;
1264}
1265
1266status_t Camera2Client::commandStartFaceDetectionL(int type) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001267 ALOGV("%s: Camera %d: Starting face detection",
1268 __FUNCTION__, mCameraId);
1269 status_t res;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001270 SharedParameters::Lock l(mParameters);
1271 switch (l.mParameters.state) {
1272 case Parameters::DISCONNECTED:
1273 case Parameters::STOPPED:
1274 case Parameters::WAITING_FOR_PREVIEW_WINDOW:
1275 case Parameters::STILL_CAPTURE:
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001276 ALOGE("%s: Camera %d: Cannot start face detection without preview active",
1277 __FUNCTION__, mCameraId);
1278 return INVALID_OPERATION;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001279 case Parameters::PREVIEW:
1280 case Parameters::RECORD:
1281 case Parameters::VIDEO_SNAPSHOT:
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001282 // Good to go for starting face detect
1283 break;
1284 }
1285 // Ignoring type
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001286 if (l.mParameters.fastInfo.bestFaceDetectMode ==
1287 ANDROID_STATS_FACE_DETECTION_OFF) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001288 ALOGE("%s: Camera %d: Face detection not supported",
1289 __FUNCTION__, mCameraId);
1290 return INVALID_OPERATION;
1291 }
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001292 if (l.mParameters.enableFaceDetect) return OK;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001293
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001294 l.mParameters.enableFaceDetect = true;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001295
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001296 res = updateRequests(l.mParameters);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001297
1298 return res;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001299}
1300
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001301status_t Camera2Client::commandStopFaceDetectionL(Parameters &params) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001302 status_t res = OK;
1303 ALOGV("%s: Camera %d: Stopping face detection",
1304 __FUNCTION__, mCameraId);
1305
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001306 if (!params.enableFaceDetect) return OK;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001307
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001308 params.enableFaceDetect = false;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001309
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001310 if (params.state == Parameters::PREVIEW
1311 || params.state == Parameters::RECORD
1312 || params.state == Parameters::VIDEO_SNAPSHOT) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001313 res = updateRequests(params);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001314 }
1315
1316 return res;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001317}
1318
1319status_t Camera2Client::commandEnableFocusMoveMsgL(bool enable) {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001320 SharedParameters::Lock l(mParameters);
1321 l.mParameters.enableFocusMoveMessages = enable;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001322
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001323 return OK;
1324}
1325
1326status_t Camera2Client::commandPingL() {
1327 // Always ping back if access is proper and device is alive
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001328 SharedParameters::Lock l(mParameters);
1329 if (l.mParameters.state != Parameters::DISCONNECTED) {
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001330 return OK;
1331 } else {
1332 return NO_INIT;
1333 }
1334}
1335
1336status_t Camera2Client::commandSetVideoBufferCountL(size_t count) {
James Dong8da4cd72012-08-04 19:58:07 -07001337 if (recordingEnabledL()) {
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001338 ALOGE("%s: Camera %d: Error setting video buffer count after "
1339 "recording was started", __FUNCTION__, mCameraId);
1340 return INVALID_OPERATION;
1341 }
1342
1343 // 32 is the current upper limit on the video buffer count for BufferQueue
1344 if (count > 32) {
1345 ALOGE("%s: Camera %d: Error setting %d as video buffer count value",
1346 __FUNCTION__, mCameraId, count);
1347 return BAD_VALUE;
1348 }
1349
1350 // Need to reallocate memory for heap
1351 if (mRecordingHeapCount != count) {
1352 if (mRecordingHeap != 0) {
1353 mRecordingHeap.clear();
1354 mRecordingHeap = NULL;
1355 }
1356 mRecordingHeapCount = count;
1357 }
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001358
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001359 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001360}
1361
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001362/** Device-related methods */
1363
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -07001364void Camera2Client::notifyError(int errorCode, int arg1, int arg2) {
1365 ALOGE("Error condition %d reported by HAL, arguments %d, %d", errorCode, arg1, arg2);
1366}
1367
1368void Camera2Client::notifyShutter(int frameNumber, nsecs_t timestamp) {
1369 ALOGV("%s: Shutter notification for frame %d at time %lld", __FUNCTION__,
1370 frameNumber, timestamp);
1371}
1372
1373void Camera2Client::notifyAutoFocus(uint8_t newState, int triggerId) {
1374 ALOGV("%s: Autofocus state now %d, last trigger %d",
1375 __FUNCTION__, newState, triggerId);
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001376 bool sendCompletedMessage = false;
1377 bool sendMovingMessage = false;
1378
1379 bool success = false;
1380 bool afInMotion = false;
1381 {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001382 SharedParameters::Lock l(mParameters);
1383 switch (l.mParameters.focusMode) {
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001384 case Parameters::FOCUS_MODE_AUTO:
1385 case Parameters::FOCUS_MODE_MACRO:
1386 // Don't send notifications upstream if they're not for the current AF
1387 // trigger. For example, if cancel was called in between, or if we
1388 // already sent a notification about this AF call.
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001389 if (triggerId != l.mParameters.currentAfTriggerId) break;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001390 switch (newState) {
1391 case ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED:
1392 success = true;
1393 // no break
1394 case ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
1395 sendCompletedMessage = true;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001396 l.mParameters.currentAfTriggerId = -1;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001397 break;
1398 case ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN:
1399 // Just starting focusing, ignore
1400 break;
1401 case ANDROID_CONTROL_AF_STATE_INACTIVE:
1402 case ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN:
1403 case ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED:
1404 default:
1405 // Unexpected in AUTO/MACRO mode
1406 ALOGE("%s: Unexpected AF state transition in AUTO/MACRO mode: %d",
1407 __FUNCTION__, newState);
1408 break;
1409 }
1410 break;
1411 case Parameters::FOCUS_MODE_CONTINUOUS_VIDEO:
1412 case Parameters::FOCUS_MODE_CONTINUOUS_PICTURE:
1413 switch (newState) {
1414 case ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED:
1415 success = true;
1416 // no break
1417 case ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
1418 // Don't send notifications upstream if they're not for
1419 // the current AF trigger. For example, if cancel was
1420 // called in between, or if we already sent a
1421 // notification about this AF call.
1422 // Send both a 'AF done' callback and a 'AF move' callback
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001423 if (triggerId != l.mParameters.currentAfTriggerId) break;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001424 sendCompletedMessage = true;
1425 afInMotion = false;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001426 if (l.mParameters.enableFocusMoveMessages &&
1427 l.mParameters.afInMotion) {
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001428 sendMovingMessage = true;
1429 }
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001430 l.mParameters.currentAfTriggerId = -1;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001431 break;
1432 case ANDROID_CONTROL_AF_STATE_INACTIVE:
1433 // Cancel was called, or we switched state; care if
1434 // currently moving
1435 afInMotion = false;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001436 if (l.mParameters.enableFocusMoveMessages &&
1437 l.mParameters.afInMotion) {
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001438 sendMovingMessage = true;
1439 }
1440 break;
1441 case ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN:
1442 // Start passive scan, inform upstream
1443 afInMotion = true;
1444 // no break
1445 case ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED:
1446 // Stop passive scan, inform upstream
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001447 if (l.mParameters.enableFocusMoveMessages) {
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001448 sendMovingMessage = true;
1449 }
1450 break;
1451 }
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001452 l.mParameters.afInMotion = afInMotion;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001453 break;
1454 case Parameters::FOCUS_MODE_EDOF:
1455 case Parameters::FOCUS_MODE_INFINITY:
1456 case Parameters::FOCUS_MODE_FIXED:
1457 default:
1458 if (newState != ANDROID_CONTROL_AF_STATE_INACTIVE) {
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -07001459 ALOGE("%s: Unexpected AF state change %d "
1460 "(ID %d) in focus mode %d",
1461 __FUNCTION__, newState, triggerId,
1462 l.mParameters.focusMode);
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001463 }
1464 }
1465 }
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001466 if (sendMovingMessage) {
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -07001467 SharedCameraClient::Lock l(mSharedCameraClient);
1468 if (l.mCameraClient != 0) {
1469 l.mCameraClient->notifyCallback(CAMERA_MSG_FOCUS_MOVE,
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001470 afInMotion ? 1 : 0, 0);
1471 }
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001472 }
Eino-Ville Talvala603b12e2012-08-08 09:25:58 -07001473 if (sendCompletedMessage) {
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -07001474 SharedCameraClient::Lock l(mSharedCameraClient);
1475 if (l.mCameraClient != 0) {
1476 l.mCameraClient->notifyCallback(CAMERA_MSG_FOCUS,
1477 success ? 1 : 0, 0);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001478 }
Eino-Ville Talvala603b12e2012-08-08 09:25:58 -07001479 }
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -07001480}
1481
1482void Camera2Client::notifyAutoExposure(uint8_t newState, int triggerId) {
1483 ALOGV("%s: Autoexposure state now %d, last trigger %d",
1484 __FUNCTION__, newState, triggerId);
1485}
1486
1487void Camera2Client::notifyAutoWhitebalance(uint8_t newState, int triggerId) {
1488 ALOGV("%s: Auto-whitebalance state now %d, last trigger %d",
1489 __FUNCTION__, newState, triggerId);
1490}
1491
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -07001492int Camera2Client::getCameraId() {
1493 return mCameraId;
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -07001494}
1495
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -07001496const sp<Camera2Device>& Camera2Client::getCameraDevice() {
1497 return mDevice;
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -07001498}
1499
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -07001500camera2::SharedParameters& Camera2Client::getParameters() {
1501 return mParameters;
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -07001502}
1503
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -07001504Camera2Client::SharedCameraClient::Lock::Lock(SharedCameraClient &client):
1505 mCameraClient(client.mCameraClient),
1506 mSharedClient(client) {
1507 mSharedClient.mCameraClientLock.lock();
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -07001508}
1509
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -07001510Camera2Client::SharedCameraClient::Lock::~Lock() {
1511 mSharedClient.mCameraClientLock.unlock();
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001512}
1513
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -07001514Camera2Client::SharedCameraClient& Camera2Client::SharedCameraClient::operator=(
1515 const sp<ICameraClient>&client) {
1516 Mutex::Autolock l(mCameraClientLock);
1517 mCameraClient = client;
1518 return *this;
1519}
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001520
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -07001521void Camera2Client::SharedCameraClient::clear() {
1522 Mutex::Autolock l(mCameraClientLock);
1523 mCameraClient.clear();
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001524}
1525
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001526void Camera2Client::onCallbackAvailable() {
1527 ATRACE_CALL();
1528 status_t res;
1529 ALOGV("%s: Camera %d: Preview callback available", __FUNCTION__, mCameraId);
1530
1531 int callbackHeapId;
1532 sp<Camera2Heap> callbackHeap;
1533 size_t heapIdx;
1534
1535 CpuConsumer::LockedBuffer imgBuffer;
1536 ALOGV("%s: Getting buffer", __FUNCTION__);
1537 res = mCallbackConsumer->lockNextBuffer(&imgBuffer);
1538 if (res != OK) {
1539 ALOGE("%s: Camera %d: Error receiving next callback buffer: "
1540 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
1541 return;
1542 }
1543
1544 {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001545 SharedParameters::Lock l(mParameters);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001546
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001547 if ( l.mParameters.state != Parameters::PREVIEW
1548 && l.mParameters.state != Parameters::RECORD
1549 && l.mParameters.state != Parameters::VIDEO_SNAPSHOT) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001550 ALOGV("%s: Camera %d: No longer streaming",
1551 __FUNCTION__, mCameraId);
1552 mCallbackConsumer->unlockBuffer(imgBuffer);
1553 return;
1554 }
1555
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001556 if (! (l.mParameters.previewCallbackFlags &
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001557 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) ) {
1558 ALOGV("%s: No longer enabled, dropping", __FUNCTION__);
1559 mCallbackConsumer->unlockBuffer(imgBuffer);
1560 return;
1561 }
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001562 if ((l.mParameters.previewCallbackFlags &
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001563 CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) &&
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001564 !l.mParameters.previewCallbackOneShot) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001565 ALOGV("%s: One shot mode, already sent, dropping", __FUNCTION__);
1566 mCallbackConsumer->unlockBuffer(imgBuffer);
1567 return;
1568 }
1569
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001570 if (imgBuffer.format != l.mParameters.previewFormat) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001571 ALOGE("%s: Camera %d: Unexpected format for callback: "
1572 "%x, expected %x", __FUNCTION__, mCameraId,
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001573 imgBuffer.format, l.mParameters.previewFormat);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001574 mCallbackConsumer->unlockBuffer(imgBuffer);
1575 return;
1576 }
1577
1578 size_t bufferSize = calculateBufferSize(imgBuffer.width, imgBuffer.height,
1579 imgBuffer.format, imgBuffer.stride);
1580 size_t currentBufferSize = (mCallbackHeap == 0) ?
1581 0 : (mCallbackHeap->mHeap->getSize() / kCallbackHeapCount);
1582 if (bufferSize != currentBufferSize) {
1583 mCallbackHeap.clear();
1584 mCallbackHeap = new Camera2Heap(bufferSize, kCallbackHeapCount,
1585 "Camera2Client::CallbackHeap");
1586 if (mCallbackHeap->mHeap->getSize() == 0) {
1587 ALOGE("%s: Camera %d: Unable to allocate memory for callbacks",
1588 __FUNCTION__, mCameraId);
1589 mCallbackConsumer->unlockBuffer(imgBuffer);
1590 return;
1591 }
1592
1593 mCallbackHeapHead = 0;
1594 mCallbackHeapFree = kCallbackHeapCount;
1595 mCallbackHeapId++;
1596 }
1597
1598 if (mCallbackHeapFree == 0) {
1599 ALOGE("%s: Camera %d: No free callback buffers, dropping frame",
1600 __FUNCTION__, mCameraId);
1601 mCallbackConsumer->unlockBuffer(imgBuffer);
1602 return;
1603 }
1604 heapIdx = mCallbackHeapHead;
1605 callbackHeap = mCallbackHeap;
1606 callbackHeapId = mCallbackHeapId;
1607
1608 mCallbackHeapHead = (mCallbackHeapHead + 1) & kCallbackHeapCount;
1609 mCallbackHeapFree--;
1610
1611 // TODO: Get rid of this memcpy by passing the gralloc queue all the way
1612 // to app
1613
1614 ssize_t offset;
1615 size_t size;
1616 sp<IMemoryHeap> heap =
1617 mCallbackHeap->mBuffers[heapIdx]->getMemory(&offset,
1618 &size);
1619 uint8_t *data = (uint8_t*)heap->getBase() + offset;
1620 memcpy(data, imgBuffer.data, bufferSize);
1621
1622 ALOGV("%s: Freeing buffer", __FUNCTION__);
1623 mCallbackConsumer->unlockBuffer(imgBuffer);
1624
1625 // In one-shot mode, stop sending callbacks after the first one
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001626 if (l.mParameters.previewCallbackFlags &
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001627 CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) {
1628 ALOGV("%s: clearing oneshot", __FUNCTION__);
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001629 l.mParameters.previewCallbackOneShot = false;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001630 }
1631 }
1632
1633 // Call outside parameter lock to allow re-entrancy from notification
1634 {
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -07001635 SharedCameraClient::Lock l(mSharedCameraClient);
1636 if (l.mCameraClient != 0) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001637 ALOGV("%s: Camera %d: Invoking client data callback",
1638 __FUNCTION__, mCameraId);
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -07001639 l.mCameraClient->dataCallback(CAMERA_MSG_PREVIEW_FRAME,
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001640 callbackHeap->mBuffers[heapIdx], NULL);
1641 }
1642 }
1643
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001644 SharedParameters::Lock l(mParameters);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001645 // Only increment free if we're still using the same heap
1646 if (mCallbackHeapId == callbackHeapId) {
1647 mCallbackHeapFree++;
1648 }
1649
1650 ALOGV("%s: exit", __FUNCTION__);
1651}
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001652
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001653void Camera2Client::onCaptureAvailable() {
1654 ATRACE_CALL();
1655 status_t res;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001656 sp<Camera2Heap> captureHeap;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001657 ALOGV("%s: Camera %d: Still capture available", __FUNCTION__, mCameraId);
1658
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001659 {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001660 SharedParameters::Lock l(mParameters);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001661 CpuConsumer::LockedBuffer imgBuffer;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001662
1663 res = mCaptureConsumer->lockNextBuffer(&imgBuffer);
1664 if (res != OK) {
1665 ALOGE("%s: Camera %d: Error receiving still image buffer: %s (%d)",
1666 __FUNCTION__, mCameraId, strerror(-res), res);
1667 return;
1668 }
1669
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001670 // TODO: Signal errors here upstream
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001671 if (l.mParameters.state != Parameters::STILL_CAPTURE &&
1672 l.mParameters.state != Parameters::VIDEO_SNAPSHOT) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001673 ALOGE("%s: Camera %d: Still image produced unexpectedly!",
1674 __FUNCTION__, mCameraId);
1675 mCaptureConsumer->unlockBuffer(imgBuffer);
1676 return;
1677 }
1678
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001679 if (imgBuffer.format != HAL_PIXEL_FORMAT_BLOB) {
1680 ALOGE("%s: Camera %d: Unexpected format for still image: "
1681 "%x, expected %x", __FUNCTION__, mCameraId,
1682 imgBuffer.format,
1683 HAL_PIXEL_FORMAT_BLOB);
1684 mCaptureConsumer->unlockBuffer(imgBuffer);
1685 return;
1686 }
1687
1688 // TODO: Optimize this to avoid memcopy
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001689 void* captureMemory = mCaptureHeap->mHeap->getBase();
1690 size_t size = mCaptureHeap->mHeap->getSize();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001691 memcpy(captureMemory, imgBuffer.data, size);
1692
1693 mCaptureConsumer->unlockBuffer(imgBuffer);
1694
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001695 switch (l.mParameters.state) {
1696 case Parameters::STILL_CAPTURE:
1697 l.mParameters.state = Parameters::STOPPED;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001698 break;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001699 case Parameters::VIDEO_SNAPSHOT:
1700 l.mParameters.state = Parameters::RECORD;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001701 break;
1702 default:
1703 ALOGE("%s: Camera %d: Unexpected state %d", __FUNCTION__,
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001704 mCameraId, l.mParameters.state);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001705 break;
1706 }
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001707
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001708 captureHeap = mCaptureHeap;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001709 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001710 // Call outside parameter locks to allow re-entrancy from notification
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -07001711 SharedCameraClient::Lock l(mSharedCameraClient);
1712 if (l.mCameraClient != 0) {
1713 l.mCameraClient->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE,
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001714 captureHeap->mBuffers[0], NULL);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001715 }
1716}
1717
1718void Camera2Client::onRecordingFrameAvailable() {
1719 ATRACE_CALL();
1720 status_t res;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001721 sp<Camera2Heap> recordingHeap;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001722 size_t heapIdx = 0;
1723 nsecs_t timestamp;
1724 {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001725 SharedParameters::Lock l(mParameters);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001726
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07001727 BufferItemConsumer::BufferItem imgBuffer;
1728 res = mRecordingConsumer->acquireBuffer(&imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001729 if (res != OK) {
1730 ALOGE("%s: Camera %d: Error receiving recording buffer: %s (%d)",
1731 __FUNCTION__, mCameraId, strerror(-res), res);
1732 return;
1733 }
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07001734 timestamp = imgBuffer.mTimestamp;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001735
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001736 mRecordingFrameCount++;
1737 ALOGV("OnRecordingFrame: Frame %d", mRecordingFrameCount);
1738
1739 // TODO: Signal errors here upstream
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001740 if (l.mParameters.state != Parameters::RECORD &&
1741 l.mParameters.state != Parameters::VIDEO_SNAPSHOT) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001742 ALOGV("%s: Camera %d: Discarding recording image buffers received after "
1743 "recording done",
1744 __FUNCTION__, mCameraId);
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07001745 mRecordingConsumer->releaseBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001746 return;
1747 }
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001748
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001749 if (mRecordingHeap == 0) {
1750 const size_t bufferSize = 4 + sizeof(buffer_handle_t);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001751 ALOGV("%s: Camera %d: Creating recording heap with %d buffers of "
1752 "size %d bytes", __FUNCTION__, mCameraId,
James Dong983cf232012-08-01 16:39:55 -07001753 mRecordingHeapCount, bufferSize);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001754
James Dong983cf232012-08-01 16:39:55 -07001755 mRecordingHeap = new Camera2Heap(bufferSize, mRecordingHeapCount,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001756 "Camera2Client::RecordingHeap");
1757 if (mRecordingHeap->mHeap->getSize() == 0) {
1758 ALOGE("%s: Camera %d: Unable to allocate memory for recording",
1759 __FUNCTION__, mCameraId);
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07001760 mRecordingConsumer->releaseBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001761 return;
1762 }
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07001763 for (size_t i = 0; i < mRecordingBuffers.size(); i++) {
1764 if (mRecordingBuffers[i].mBuf !=
1765 BufferItemConsumer::INVALID_BUFFER_SLOT) {
1766 ALOGE("%s: Camera %d: Non-empty recording buffers list!",
1767 __FUNCTION__, mCameraId);
1768 }
1769 }
1770 mRecordingBuffers.clear();
1771 mRecordingBuffers.setCapacity(mRecordingHeapCount);
1772 mRecordingBuffers.insertAt(0, mRecordingHeapCount);
1773
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001774 mRecordingHeapHead = 0;
James Dong983cf232012-08-01 16:39:55 -07001775 mRecordingHeapFree = mRecordingHeapCount;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001776 }
1777
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001778 if ( mRecordingHeapFree == 0) {
1779 ALOGE("%s: Camera %d: No free recording buffers, dropping frame",
1780 __FUNCTION__, mCameraId);
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07001781 mRecordingConsumer->releaseBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001782 return;
1783 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001784
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001785 heapIdx = mRecordingHeapHead;
James Dong983cf232012-08-01 16:39:55 -07001786 mRecordingHeapHead = (mRecordingHeapHead + 1) % mRecordingHeapCount;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001787 mRecordingHeapFree--;
1788
1789 ALOGV("%s: Camera %d: Timestamp %lld",
1790 __FUNCTION__, mCameraId, timestamp);
1791
1792 ssize_t offset;
1793 size_t size;
1794 sp<IMemoryHeap> heap =
1795 mRecordingHeap->mBuffers[heapIdx]->getMemory(&offset,
1796 &size);
1797
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001798 uint8_t *data = (uint8_t*)heap->getBase() + offset;
1799 uint32_t type = kMetadataBufferTypeGrallocSource;
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07001800 *((uint32_t*)data) = type;
1801 *((buffer_handle_t*)(data + 4)) = imgBuffer.mGraphicBuffer->handle;
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001802 ALOGV("%s: Camera %d: Sending out buffer_handle_t %p",
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07001803 __FUNCTION__, mCameraId, imgBuffer.mGraphicBuffer->handle);
1804 mRecordingBuffers.replaceAt(imgBuffer, heapIdx);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001805 recordingHeap = mRecordingHeap;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001806 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001807
1808 // Call outside locked parameters to allow re-entrancy from notification
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -07001809 SharedCameraClient::Lock l(mSharedCameraClient);
1810 if (l.mCameraClient != 0) {
1811 l.mCameraClient->dataCallbackTimestamp(timestamp,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001812 CAMERA_MSG_VIDEO_FRAME,
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001813 recordingHeap->mBuffers[heapIdx]);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001814 }
1815}
1816
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001817/** Utility methods */
1818
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001819status_t Camera2Client::updateRequests(const Parameters &params) {
1820 status_t res;
1821
1822 res = updatePreviewRequest(params);
1823 if (res != OK) {
1824 ALOGE("%s: Camera %d: Unable to update preview request: %s (%d)",
1825 __FUNCTION__, mCameraId, strerror(-res), res);
1826 return res;
1827 }
1828 res = updateCaptureRequest(params);
1829 if (res != OK) {
1830 ALOGE("%s: Camera %d: Unable to update capture request: %s (%d)",
1831 __FUNCTION__, mCameraId, strerror(-res), res);
1832 return res;
1833 }
1834
1835 res = updateRecordingRequest(params);
1836 if (res != OK) {
1837 ALOGE("%s: Camera %d: Unable to update recording request: %s (%d)",
1838 __FUNCTION__, mCameraId, strerror(-res), res);
1839 return res;
1840 }
1841
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001842 if (params.state == Parameters::PREVIEW) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001843 res = mDevice->setStreamingRequest(mPreviewRequest);
1844 if (res != OK) {
1845 ALOGE("%s: Camera %d: Error streaming new preview request: %s (%d)",
1846 __FUNCTION__, mCameraId, strerror(-res), res);
1847 return res;
1848 }
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001849 } else if (params.state == Parameters::RECORD ||
1850 params.state == Parameters::VIDEO_SNAPSHOT) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001851 res = mDevice->setStreamingRequest(mRecordingRequest);
1852 if (res != OK) {
1853 ALOGE("%s: Camera %d: Error streaming new record request: %s (%d)",
1854 __FUNCTION__, mCameraId, strerror(-res), res);
1855 return res;
1856 }
1857 }
1858 return res;
1859}
1860
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001861status_t Camera2Client::updatePreviewStream(const Parameters &params) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001862 ATRACE_CALL();
1863 status_t res;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001864
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001865 if (mPreviewStreamId != NO_STREAM) {
1866 // Check if stream parameters have to change
1867 uint32_t currentWidth, currentHeight;
1868 res = mDevice->getStreamInfo(mPreviewStreamId,
1869 &currentWidth, &currentHeight, 0);
1870 if (res != OK) {
1871 ALOGE("%s: Camera %d: Error querying preview stream info: "
1872 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
1873 return res;
1874 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001875 if (currentWidth != (uint32_t)params.previewWidth ||
1876 currentHeight != (uint32_t)params.previewHeight) {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -07001877 ALOGV("%s: Camera %d: Preview size switch: %d x %d -> %d x %d",
1878 __FUNCTION__, mCameraId, currentWidth, currentHeight,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001879 params.previewWidth, params.previewHeight);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001880 res = mDevice->waitUntilDrained();
1881 if (res != OK) {
1882 ALOGE("%s: Camera %d: Error waiting for preview to drain: "
1883 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
1884 return res;
1885 }
1886 res = mDevice->deleteStream(mPreviewStreamId);
1887 if (res != OK) {
1888 ALOGE("%s: Camera %d: Unable to delete old output stream "
1889 "for preview: %s (%d)", __FUNCTION__, mCameraId,
1890 strerror(-res), res);
1891 return res;
1892 }
1893 mPreviewStreamId = NO_STREAM;
1894 }
1895 }
1896
1897 if (mPreviewStreamId == NO_STREAM) {
1898 res = mDevice->createStream(mPreviewWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001899 params.previewWidth, params.previewHeight,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001900 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0,
1901 &mPreviewStreamId);
1902 if (res != OK) {
1903 ALOGE("%s: Camera %d: Unable to create preview stream: %s (%d)",
1904 __FUNCTION__, mCameraId, strerror(-res), res);
1905 return res;
1906 }
1907 }
1908
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001909 res = mDevice->setStreamTransform(mPreviewStreamId,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001910 params.previewTransform);
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001911 if (res != OK) {
1912 ALOGE("%s: Camera %d: Unable to set preview stream transform: "
1913 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
1914 return res;
1915 }
1916
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001917 return OK;
1918}
1919
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001920status_t Camera2Client::updatePreviewRequest(const Parameters &params) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001921 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001922 status_t res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001923 if (mPreviewRequest.entryCount() == 0) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001924 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
1925 &mPreviewRequest);
1926 if (res != OK) {
1927 ALOGE("%s: Camera %d: Unable to create default preview request: "
1928 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
1929 return res;
1930 }
1931 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001932
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001933 res = updateRequestCommon(&mPreviewRequest, params);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001934 if (res != OK) {
1935 ALOGE("%s: Camera %d: Unable to update common entries of preview "
1936 "request: %s (%d)", __FUNCTION__, mCameraId,
1937 strerror(-res), res);
1938 return res;
1939 }
1940
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001941 return OK;
1942}
1943
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001944status_t Camera2Client::updateCallbackStream(const Parameters &params) {
1945 status_t res;
1946
1947 if (mCallbackConsumer == 0) {
1948 // Create CPU buffer queue endpoint
1949 mCallbackConsumer = new CpuConsumer(kCallbackHeapCount);
1950 mCallbackWaiter = new CallbackWaiter(this);
1951 mCallbackConsumer->setFrameAvailableListener(mCallbackWaiter);
1952 mCallbackConsumer->setName(String8("Camera2Client::CallbackConsumer"));
1953 mCallbackWindow = new SurfaceTextureClient(
1954 mCallbackConsumer->getProducerInterface());
1955 }
1956
1957 if (mCallbackStreamId != NO_STREAM) {
1958 // Check if stream parameters have to change
1959 uint32_t currentWidth, currentHeight, currentFormat;
1960 res = mDevice->getStreamInfo(mCallbackStreamId,
1961 &currentWidth, &currentHeight, &currentFormat);
1962 if (res != OK) {
1963 ALOGE("%s: Camera %d: Error querying callback output stream info: "
1964 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
1965 return res;
1966 }
1967 if (currentWidth != (uint32_t)params.previewWidth ||
1968 currentHeight != (uint32_t)params.previewHeight ||
1969 currentFormat != (uint32_t)params.previewFormat) {
1970 // Since size should only change while preview is not running,
1971 // assuming that all existing use of old callback stream is
1972 // completed.
1973 res = mDevice->deleteStream(mCallbackStreamId);
1974 if (res != OK) {
1975 ALOGE("%s: Camera %d: Unable to delete old output stream "
1976 "for callbacks: %s (%d)", __FUNCTION__, mCameraId,
1977 strerror(-res), res);
1978 return res;
1979 }
1980 mCallbackStreamId = NO_STREAM;
1981 }
1982 }
1983
1984 if (mCallbackStreamId == NO_STREAM) {
1985 ALOGV("Creating callback stream: %d %d format 0x%x",
1986 params.previewWidth, params.previewHeight,
1987 params.previewFormat);
1988 res = mDevice->createStream(mCallbackWindow,
1989 params.previewWidth, params.previewHeight,
1990 params.previewFormat, 0, &mCallbackStreamId);
1991 if (res != OK) {
1992 ALOGE("%s: Camera %d: Can't create output stream for callbacks: "
1993 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
1994 return res;
1995 }
1996 }
1997
1998 return OK;
1999}
2000
2001
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002002status_t Camera2Client::updateCaptureStream(const Parameters &params) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002003 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002004 status_t res;
2005 // Find out buffer size for JPEG
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002006 camera_metadata_ro_entry_t maxJpegSize =
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07002007 mParameters.staticInfo(ANDROID_JPEG_MAX_SIZE);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002008 if (maxJpegSize.count == 0) {
2009 ALOGE("%s: Camera %d: Can't find ANDROID_JPEG_MAX_SIZE!",
2010 __FUNCTION__, mCameraId);
2011 return INVALID_OPERATION;
2012 }
2013
2014 if (mCaptureConsumer == 0) {
2015 // Create CPU buffer queue endpoint
2016 mCaptureConsumer = new CpuConsumer(1);
2017 mCaptureConsumer->setFrameAvailableListener(new CaptureWaiter(this));
2018 mCaptureConsumer->setName(String8("Camera2Client::CaptureConsumer"));
2019 mCaptureWindow = new SurfaceTextureClient(
2020 mCaptureConsumer->getProducerInterface());
2021 // Create memory for API consumption
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002022 mCaptureHeap = new Camera2Heap(maxJpegSize.data.i32[0], 1,
2023 "Camera2Client::CaptureHeap");
2024 if (mCaptureHeap->mHeap->getSize() == 0) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002025 ALOGE("%s: Camera %d: Unable to allocate memory for capture",
2026 __FUNCTION__, mCameraId);
2027 return NO_MEMORY;
2028 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002029 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002030
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002031 if (mCaptureStreamId != NO_STREAM) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002032 // Check if stream parameters have to change
2033 uint32_t currentWidth, currentHeight;
2034 res = mDevice->getStreamInfo(mCaptureStreamId,
2035 &currentWidth, &currentHeight, 0);
2036 if (res != OK) {
2037 ALOGE("%s: Camera %d: Error querying capture output stream info: "
2038 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2039 return res;
2040 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002041 if (currentWidth != (uint32_t)params.pictureWidth ||
2042 currentHeight != (uint32_t)params.pictureHeight) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002043 res = mDevice->deleteStream(mCaptureStreamId);
2044 if (res != OK) {
2045 ALOGE("%s: Camera %d: Unable to delete old output stream "
2046 "for capture: %s (%d)", __FUNCTION__, mCameraId,
2047 strerror(-res), res);
2048 return res;
2049 }
2050 mCaptureStreamId = NO_STREAM;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002051 }
2052 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002053
2054 if (mCaptureStreamId == NO_STREAM) {
2055 // Create stream for HAL production
2056 res = mDevice->createStream(mCaptureWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002057 params.pictureWidth, params.pictureHeight,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002058 HAL_PIXEL_FORMAT_BLOB, maxJpegSize.data.i32[0],
2059 &mCaptureStreamId);
2060 if (res != OK) {
2061 ALOGE("%s: Camera %d: Can't create output stream for capture: "
2062 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2063 return res;
2064 }
2065
2066 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002067 return OK;
2068}
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002069
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002070status_t Camera2Client::updateCaptureRequest(const Parameters &params) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002071 ATRACE_CALL();
2072 status_t res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002073 if (mCaptureRequest.entryCount() == 0) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002074 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_STILL_CAPTURE,
2075 &mCaptureRequest);
2076 if (res != OK) {
2077 ALOGE("%s: Camera %d: Unable to create default still image request:"
2078 " %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2079 return res;
2080 }
2081 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002082
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002083 res = updateRequestCommon(&mCaptureRequest, params);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002084 if (res != OK) {
2085 ALOGE("%s: Camera %d: Unable to update common entries of capture "
2086 "request: %s (%d)", __FUNCTION__, mCameraId,
2087 strerror(-res), res);
2088 return res;
2089 }
2090
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002091 res = mCaptureRequest.update(ANDROID_JPEG_THUMBNAIL_SIZE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002092 params.jpegThumbSize, 2);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002093 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002094 res = mCaptureRequest.update(ANDROID_JPEG_THUMBNAIL_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002095 &params.jpegThumbQuality, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002096 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002097 res = mCaptureRequest.update(ANDROID_JPEG_QUALITY,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002098 &params.jpegQuality, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002099 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002100 res = mCaptureRequest.update(
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002101 ANDROID_JPEG_ORIENTATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002102 &params.jpegRotation, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002103 if (res != OK) return res;
2104
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002105 if (params.gpsEnabled) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002106 res = mCaptureRequest.update(
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002107 ANDROID_JPEG_GPS_COORDINATES,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002108 params.gpsCoordinates, 3);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002109 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002110 res = mCaptureRequest.update(
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002111 ANDROID_JPEG_GPS_TIMESTAMP,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002112 &params.gpsTimestamp, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002113 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002114 res = mCaptureRequest.update(
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002115 ANDROID_JPEG_GPS_PROCESSING_METHOD,
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002116 params.gpsProcessingMethod);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002117 if (res != OK) return res;
2118 } else {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002119 res = mCaptureRequest.erase(ANDROID_JPEG_GPS_COORDINATES);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002120 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002121 res = mCaptureRequest.erase(ANDROID_JPEG_GPS_TIMESTAMP);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002122 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002123 res = mCaptureRequest.erase(ANDROID_JPEG_GPS_PROCESSING_METHOD);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002124 if (res != OK) return res;
2125 }
2126
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07002127 return OK;
2128}
2129
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002130status_t Camera2Client::updateRecordingRequest(const Parameters &params) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002131 ATRACE_CALL();
2132 status_t res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002133 if (mRecordingRequest.entryCount() == 0) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002134 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_VIDEO_RECORD,
2135 &mRecordingRequest);
2136 if (res != OK) {
2137 ALOGE("%s: Camera %d: Unable to create default recording request:"
2138 " %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2139 return res;
2140 }
2141 }
2142
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002143 res = updateRequestCommon(&mRecordingRequest, params);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002144 if (res != OK) {
2145 ALOGE("%s: Camera %d: Unable to update common entries of recording "
2146 "request: %s (%d)", __FUNCTION__, mCameraId,
2147 strerror(-res), res);
2148 return res;
2149 }
2150
2151 return OK;
2152}
2153
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002154status_t Camera2Client::updateRecordingStream(const Parameters &params) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002155 status_t res;
2156
2157 if (mRecordingConsumer == 0) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002158 // Create CPU buffer queue endpoint. We need one more buffer here so that we can
2159 // always acquire and free a buffer when the heap is full; otherwise the consumer
2160 // will have buffers in flight we'll never clear out.
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07002161 mRecordingConsumer = new BufferItemConsumer(
2162 GRALLOC_USAGE_HW_VIDEO_ENCODER,
2163 mRecordingHeapCount + 1,
2164 true);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002165 mRecordingConsumer->setFrameAvailableListener(new RecordingWaiter(this));
2166 mRecordingConsumer->setName(String8("Camera2Client::RecordingConsumer"));
2167 mRecordingWindow = new SurfaceTextureClient(
2168 mRecordingConsumer->getProducerInterface());
2169 // Allocate memory later, since we don't know buffer size until receipt
2170 }
2171
2172 if (mRecordingStreamId != NO_STREAM) {
2173 // Check if stream parameters have to change
2174 uint32_t currentWidth, currentHeight;
2175 res = mDevice->getStreamInfo(mRecordingStreamId,
2176 &currentWidth, &currentHeight, 0);
2177 if (res != OK) {
2178 ALOGE("%s: Camera %d: Error querying recording output stream info: "
2179 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2180 return res;
2181 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002182 if (currentWidth != (uint32_t)params.videoWidth ||
2183 currentHeight != (uint32_t)params.videoHeight) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002184 // TODO: Should wait to be sure previous recording has finished
2185 res = mDevice->deleteStream(mRecordingStreamId);
2186 if (res != OK) {
2187 ALOGE("%s: Camera %d: Unable to delete old output stream "
2188 "for recording: %s (%d)", __FUNCTION__, mCameraId,
2189 strerror(-res), res);
2190 return res;
2191 }
2192 mRecordingStreamId = NO_STREAM;
2193 }
2194 }
2195
2196 if (mRecordingStreamId == NO_STREAM) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002197 mRecordingFrameCount = 0;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002198 res = mDevice->createStream(mRecordingWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002199 params.videoWidth, params.videoHeight,
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07002200 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0, &mRecordingStreamId);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07002201 if (res != OK) {
2202 ALOGE("%s: Camera %d: Can't create output stream for recording: "
2203 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
2204 return res;
2205 }
2206 }
2207
2208 return OK;
2209}
2210
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002211status_t Camera2Client::updateRequestCommon(CameraMetadata *request,
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07002212 const Parameters &params) const {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002213 ATRACE_CALL();
2214 status_t res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002215 res = request->update(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
2216 params.previewFpsRange, 2);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002217 if (res != OK) return res;
2218
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002219 uint8_t wbMode = params.autoWhiteBalanceLock ?
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002220 (uint8_t)ANDROID_CONTROL_AWB_LOCKED : params.wbMode;
2221 res = request->update(ANDROID_CONTROL_AWB_MODE,
2222 &wbMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002223 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002224 res = request->update(ANDROID_CONTROL_EFFECT_MODE,
2225 &params.effectMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002226 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002227 res = request->update(ANDROID_CONTROL_AE_ANTIBANDING_MODE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002228 &params.antibandingMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002229 if (res != OK) return res;
2230
2231 uint8_t controlMode =
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002232 (params.sceneMode == ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED) ?
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002233 ANDROID_CONTROL_AUTO : ANDROID_CONTROL_USE_SCENE_MODE;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002234 res = request->update(ANDROID_CONTROL_MODE,
2235 &controlMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002236 if (res != OK) return res;
2237 if (controlMode == ANDROID_CONTROL_USE_SCENE_MODE) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002238 res = request->update(ANDROID_CONTROL_SCENE_MODE,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002239 &params.sceneMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002240 if (res != OK) return res;
2241 }
2242
2243 uint8_t flashMode = ANDROID_FLASH_OFF;
2244 uint8_t aeMode;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002245 switch (params.flashMode) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002246 case Parameters::FLASH_MODE_OFF:
2247 aeMode = ANDROID_CONTROL_AE_ON; break;
2248 case Parameters::FLASH_MODE_AUTO:
2249 aeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH; break;
2250 case Parameters::FLASH_MODE_ON:
2251 aeMode = ANDROID_CONTROL_AE_ON_ALWAYS_FLASH; break;
2252 case Parameters::FLASH_MODE_TORCH:
2253 aeMode = ANDROID_CONTROL_AE_ON;
2254 flashMode = ANDROID_FLASH_TORCH;
2255 break;
2256 case Parameters::FLASH_MODE_RED_EYE:
2257 aeMode = ANDROID_CONTROL_AE_ON_AUTO_FLASH_REDEYE; break;
2258 default:
2259 ALOGE("%s: Camera %d: Unknown flash mode %d", __FUNCTION__,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002260 mCameraId, params.flashMode);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002261 return BAD_VALUE;
2262 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002263 if (params.autoExposureLock) aeMode = ANDROID_CONTROL_AE_LOCKED;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002264
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002265 res = request->update(ANDROID_FLASH_MODE,
2266 &flashMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002267 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002268 res = request->update(ANDROID_CONTROL_AE_MODE,
2269 &aeMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002270 if (res != OK) return res;
2271
2272 float focusDistance = 0; // infinity focus in diopters
2273 uint8_t focusMode;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002274 switch (params.focusMode) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002275 case Parameters::FOCUS_MODE_AUTO:
2276 case Parameters::FOCUS_MODE_MACRO:
2277 case Parameters::FOCUS_MODE_CONTINUOUS_VIDEO:
2278 case Parameters::FOCUS_MODE_CONTINUOUS_PICTURE:
2279 case Parameters::FOCUS_MODE_EDOF:
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002280 focusMode = params.focusMode;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002281 break;
2282 case Parameters::FOCUS_MODE_INFINITY:
2283 case Parameters::FOCUS_MODE_FIXED:
2284 focusMode = ANDROID_CONTROL_AF_OFF;
2285 break;
2286 default:
2287 ALOGE("%s: Camera %d: Unknown focus mode %d", __FUNCTION__,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002288 mCameraId, params.focusMode);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002289 return BAD_VALUE;
2290 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002291 res = request->update(ANDROID_LENS_FOCUS_DISTANCE,
2292 &focusDistance, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002293 if (res != OK) return res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002294 res = request->update(ANDROID_CONTROL_AF_MODE,
2295 &focusMode, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002296 if (res != OK) return res;
2297
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002298 size_t focusingAreasSize = params.focusingAreas.size() * 5;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002299 int32_t *focusingAreas = new int32_t[focusingAreasSize];
2300 for (size_t i = 0; i < focusingAreasSize; i += 5) {
Eino-Ville Talvalaf17b6cf2012-08-25 17:12:18 -07002301 if (params.focusingAreas[i].weight != 0) {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07002302 focusingAreas[i + 0] =
2303 params.normalizedXToArray(params.focusingAreas[i].left);
2304 focusingAreas[i + 1] =
2305 params.normalizedYToArray(params.focusingAreas[i].top);
2306 focusingAreas[i + 2] =
2307 params.normalizedXToArray(params.focusingAreas[i].right);
2308 focusingAreas[i + 3] =
2309 params.normalizedYToArray(params.focusingAreas[i].bottom);
Eino-Ville Talvalaf17b6cf2012-08-25 17:12:18 -07002310 } else {
2311 focusingAreas[i + 0] = 0;
2312 focusingAreas[i + 1] = 0;
2313 focusingAreas[i + 2] = 0;
2314 focusingAreas[i + 3] = 0;
2315 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002316 focusingAreas[i + 4] = params.focusingAreas[i].weight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002317 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002318 res = request->update(ANDROID_CONTROL_AF_REGIONS,
2319 focusingAreas,focusingAreasSize);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002320 if (res != OK) return res;
2321 delete[] focusingAreas;
2322
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002323 res = request->update(ANDROID_CONTROL_AE_EXP_COMPENSATION,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002324 &params.exposureCompensation, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002325 if (res != OK) return res;
2326
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002327 size_t meteringAreasSize = params.meteringAreas.size() * 5;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002328 int32_t *meteringAreas = new int32_t[meteringAreasSize];
2329 for (size_t i = 0; i < meteringAreasSize; i += 5) {
Eino-Ville Talvalaf17b6cf2012-08-25 17:12:18 -07002330 if (params.meteringAreas[i].weight != 0) {
2331 meteringAreas[i + 0] =
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07002332 params.normalizedXToArray(params.meteringAreas[i].left);
Eino-Ville Talvalaf17b6cf2012-08-25 17:12:18 -07002333 meteringAreas[i + 1] =
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07002334 params.normalizedYToArray(params.meteringAreas[i].top);
Eino-Ville Talvalaf17b6cf2012-08-25 17:12:18 -07002335 meteringAreas[i + 2] =
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07002336 params.normalizedXToArray(params.meteringAreas[i].right);
Eino-Ville Talvalaf17b6cf2012-08-25 17:12:18 -07002337 meteringAreas[i + 3] =
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07002338 params.normalizedYToArray(params.meteringAreas[i].bottom);
Eino-Ville Talvalaf17b6cf2012-08-25 17:12:18 -07002339 } else {
2340 meteringAreas[i + 0] = 0;
2341 meteringAreas[i + 1] = 0;
2342 meteringAreas[i + 2] = 0;
2343 meteringAreas[i + 3] = 0;
2344 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002345 meteringAreas[i + 4] = params.meteringAreas[i].weight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002346 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002347 res = request->update(ANDROID_CONTROL_AE_REGIONS,
2348 meteringAreas, meteringAreasSize);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002349 if (res != OK) return res;
2350
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002351 res = request->update(ANDROID_CONTROL_AWB_REGIONS,
2352 meteringAreas, meteringAreasSize);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002353 if (res != OK) return res;
2354 delete[] meteringAreas;
2355
2356 // Need to convert zoom index into a crop rectangle. The rectangle is
2357 // chosen to maximize its area on the sensor
2358
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002359 camera_metadata_ro_entry_t maxDigitalZoom =
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07002360 mParameters.staticInfo(ANDROID_SCALER_AVAILABLE_MAX_ZOOM);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002361 float zoomIncrement = (maxDigitalZoom.data.f[0] - 1) /
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07002362 (params.NUM_ZOOM_STEPS-1);
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002363 float zoomRatio = 1 + zoomIncrement * params.zoom;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002364
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002365 float zoomLeft, zoomTop, zoomWidth, zoomHeight;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002366 if (params.previewWidth >= params.previewHeight) {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07002367 zoomWidth = params.fastInfo.arrayWidth / zoomRatio;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002368 zoomHeight = zoomWidth *
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002369 params.previewHeight / params.previewWidth;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002370 } else {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07002371 zoomHeight = params.fastInfo.arrayHeight / zoomRatio;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002372 zoomWidth = zoomHeight *
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002373 params.previewWidth / params.previewHeight;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002374 }
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07002375 zoomLeft = (params.fastInfo.arrayWidth - zoomWidth) / 2;
2376 zoomTop = (params.fastInfo.arrayHeight - zoomHeight) / 2;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002377
2378 int32_t cropRegion[3] = { zoomLeft, zoomTop, zoomWidth };
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002379 res = request->update(ANDROID_SCALER_CROP_REGION,
2380 cropRegion, 3);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002381 if (res != OK) return res;
2382
2383 // TODO: Decide how to map recordingHint, or whether just to ignore it
2384
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07002385 uint8_t vstabMode = params.videoStabilization ?
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002386 ANDROID_CONTROL_VIDEO_STABILIZATION_ON :
2387 ANDROID_CONTROL_VIDEO_STABILIZATION_OFF;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002388 res = request->update(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002389 &vstabMode, 1);
2390 if (res != OK) return res;
2391
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002392 uint8_t faceDetectMode = params.enableFaceDetect ?
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07002393 params.fastInfo.bestFaceDetectMode :
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002394 (uint8_t)ANDROID_STATS_FACE_DETECTION_OFF;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07002395 res = request->update(ANDROID_STATS_FACE_DETECT_MODE,
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002396 &faceDetectMode, 1);
2397 if (res != OK) return res;
2398
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07002399 return OK;
2400}
2401
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002402size_t Camera2Client::calculateBufferSize(int width, int height,
2403 int format, int stride) {
2404 switch (format) {
2405 case HAL_PIXEL_FORMAT_YCbCr_422_SP: // NV16
2406 return width * height * 2;
2407 case HAL_PIXEL_FORMAT_YCrCb_420_SP: // NV21
2408 return width * height * 3 / 2;
2409 case HAL_PIXEL_FORMAT_YCbCr_422_I: // YUY2
2410 return width * height * 2;
2411 case HAL_PIXEL_FORMAT_YV12: { // YV12
2412 size_t ySize = stride * height;
Eino-Ville Talvalaf17b6cf2012-08-25 17:12:18 -07002413 size_t uvStride = (stride / 2 + 0xF) & ~0xF;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07002414 size_t uvSize = uvStride * height / 2;
2415 return ySize + uvSize * 2;
2416 }
2417 case HAL_PIXEL_FORMAT_RGB_565:
2418 return width * height * 2;
2419 case HAL_PIXEL_FORMAT_RGBA_8888:
2420 return width * height * 4;
2421 case HAL_PIXEL_FORMAT_RAW_SENSOR:
2422 return width * height * 2;
2423 default:
2424 ALOGE("%s: Unknown preview format: %x",
2425 __FUNCTION__, format);
2426 return 0;
2427 }
2428}
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07002429
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07002430} // namespace android