blob: 4fad83e759f6795098f9497edc77490b58338457 [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>
James Painterc3dbf1a2012-09-05 18:02:32 -070028#include "camera2/Parameters.h"
James Painterfe140e82012-09-07 16:36:50 -070029#include "Camera2Client.h"
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070030
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 {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -070035using namespace camera2;
36
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070037static int getCallingPid() {
38 return IPCThreadState::self()->getCallingPid();
39}
40
41static int getCallingUid() {
42 return IPCThreadState::self()->getCallingUid();
43}
44
45// Interface used by CameraService
46
47Camera2Client::Camera2Client(const sp<CameraService>& cameraService,
48 const sp<ICameraClient>& cameraClient,
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070049 int cameraId,
50 int cameraFacing,
51 int clientPid):
52 Client(cameraService, cameraClient,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070053 cameraId, cameraFacing, clientPid),
Eino-Ville Talvala177bd342012-08-28 01:25:43 -070054 mSharedCameraClient(cameraClient),
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 Talvala9cca4c62012-06-15 15:41:44 -070057 mRecordingStreamId(NO_STREAM),
James Dong983cf232012-08-01 16:39:55 -070058 mRecordingHeapCount(kDefaultRecordingHeapCount)
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070059{
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070060 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -070061 ALOGI("Camera %d: Opened", cameraId);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070062
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070063 mDevice = new Camera2Device(cameraId);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -070064
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -070065 SharedParameters::Lock l(mParameters);
66 l.mParameters.state = Parameters::DISCONNECTED;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070067}
68
Eino-Ville Talvala3a609142012-07-31 14:36:26 -070069status_t Camera2Client::checkPid(const char* checkLocation) const {
70 int callingPid = getCallingPid();
71 if (callingPid == mClientPid) return NO_ERROR;
72
73 ALOGE("%s: attempt to use a locked camera from a different process"
74 " (old pid %d, new pid %d)", checkLocation, mClientPid, callingPid);
75 return PERMISSION_DENIED;
76}
77
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070078status_t Camera2Client::initialize(camera_module_t *module)
79{
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -070080 ATRACE_CALL();
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -070081 ALOGV("%s: Initializing client for camera %d", __FUNCTION__, mCameraId);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070082 status_t res;
83
84 res = mDevice->initialize(module);
85 if (res != OK) {
86 ALOGE("%s: Camera %d: unable to initialize device: %s (%d)",
87 __FUNCTION__, mCameraId, strerror(-res), res);
88 return NO_INIT;
89 }
90
Eino-Ville Talvala174181e2012-08-03 13:53:39 -070091 res = mDevice->setNotifyCallback(this);
92
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -070093 SharedParameters::Lock l(mParameters);
94
95 res = l.mParameters.initialize(&(mDevice->info()));
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070096 if (res != OK) {
97 ALOGE("%s: Camera %d: unable to build defaults: %s (%d)",
98 __FUNCTION__, mCameraId, strerror(-res), res);
99 return NO_INIT;
100 }
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -0700101
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700102 String8 threadName;
Eino-Ville Talvala177bd342012-08-28 01:25:43 -0700103
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700104 mFrameProcessor = new FrameProcessor(this);
105 threadName = String8::format("Camera2Client[%d]::FrameProcessor",
106 mCameraId);
107 mFrameProcessor->run(threadName.string());
108
109 mCaptureSequencer = new CaptureSequencer(this);
110 threadName = String8::format("Camera2Client[%d]::CaptureSequencer",
111 mCameraId);
112 mCaptureSequencer->run(threadName.string());
113
114 mJpegProcessor = new JpegProcessor(this, mCaptureSequencer);
115 threadName = String8::format("Camera2Client[%d]::JpegProcessor",
116 mCameraId);
117 mJpegProcessor->run(threadName.string());
118
119 mZslProcessor = new ZslProcessor(this, mCaptureSequencer);
120 threadName = String8::format("Camera2Client[%d]::ZslProcessor",
121 mCameraId);
122 mZslProcessor->run(threadName.string());
Eino-Ville Talvala177bd342012-08-28 01:25:43 -0700123
Eino-Ville Talvala28639182012-08-28 11:34:14 -0700124 mCallbackProcessor = new CallbackProcessor(this);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700125 threadName = String8::format("Camera2Client[%d]::CallbackProcessor",
126 mCameraId);
127 mCallbackProcessor->run(threadName.string());
Eino-Ville Talvala28639182012-08-28 11:34:14 -0700128
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700129 if (gLogLevel >= 1) {
130 ALOGD("%s: Default parameters converted from camera %d:", __FUNCTION__,
131 mCameraId);
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700132 ALOGD("%s", l.mParameters.paramsFlattened.string());
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700133 }
134
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700135 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700136}
137
138Camera2Client::~Camera2Client() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700139 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700140 ALOGV("Camera %d: Shutting down", mCameraId);
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700141
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700142 mDestructionStarted = true;
143
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700144 // Rewrite mClientPid to allow shutdown by CameraService
145 mClientPid = getCallingPid();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700146 disconnect();
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -0700147
148 mFrameProcessor->requestExit();
Eino-Ville Talvala7d8b92b2012-09-05 19:02:43 -0700149 mCaptureSequencer->requestExit();
150 mJpegProcessor->requestExit();
151 mZslProcessor->requestExit();
152 mCallbackProcessor->requestExit();
153
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700154 ALOGI("Camera %d: Closed", mCameraId);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700155}
156
157status_t Camera2Client::dump(int fd, const Vector<String16>& args) {
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700158 String8 result;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700159 result.appendFormat("Client2[%d] (%p) PID: %d, dump:\n",
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700160 mCameraId,
161 getCameraClient()->asBinder().get(),
162 mClientPid);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700163 result.append(" State: ");
164#define CASE_APPEND_ENUM(x) case x: result.append(#x "\n"); break;
165
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700166 const Parameters& p = mParameters.unsafeAccess();
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700167
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700168 result.append(Parameters::getStateName(p.state));
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700169
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700170 result.append("\n Current parameters:\n");
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700171 result.appendFormat(" Preview size: %d x %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700172 p.previewWidth, p.previewHeight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700173 result.appendFormat(" Preview FPS range: %d - %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700174 p.previewFpsRange[0], p.previewFpsRange[1]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700175 result.appendFormat(" Preview HAL pixel format: 0x%x\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700176 p.previewFormat);
Eino-Ville Talvala11b7cde2012-06-15 12:37:35 -0700177 result.appendFormat(" Preview transform: %x\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700178 p.previewTransform);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700179 result.appendFormat(" Picture size: %d x %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700180 p.pictureWidth, p.pictureHeight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700181 result.appendFormat(" Jpeg thumbnail size: %d x %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700182 p.jpegThumbSize[0], p.jpegThumbSize[1]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700183 result.appendFormat(" Jpeg quality: %d, thumbnail quality: %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700184 p.jpegQuality, p.jpegThumbQuality);
185 result.appendFormat(" Jpeg rotation: %d\n", p.jpegRotation);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700186 result.appendFormat(" GPS tags %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700187 p.gpsEnabled ? "enabled" : "disabled");
188 if (p.gpsEnabled) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700189 result.appendFormat(" GPS lat x long x alt: %f x %f x %f\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700190 p.gpsCoordinates[0], p.gpsCoordinates[1],
191 p.gpsCoordinates[2]);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700192 result.appendFormat(" GPS timestamp: %lld\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700193 p.gpsTimestamp);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700194 result.appendFormat(" GPS processing method: %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700195 p.gpsProcessingMethod.string());
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700196 }
197
198 result.append(" White balance mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700199 switch (p.wbMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700200 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_AUTO)
201 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_INCANDESCENT)
202 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_FLUORESCENT)
203 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_WARM_FLUORESCENT)
204 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_DAYLIGHT)
205 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_CLOUDY_DAYLIGHT)
206 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_TWILIGHT)
207 CASE_APPEND_ENUM(ANDROID_CONTROL_AWB_SHADE)
208 default: result.append("UNKNOWN\n");
209 }
210
211 result.append(" Effect mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700212 switch (p.effectMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700213 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_OFF)
214 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_MONO)
215 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_NEGATIVE)
216 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_SOLARIZE)
217 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_SEPIA)
218 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_POSTERIZE)
219 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_WHITEBOARD)
220 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_BLACKBOARD)
221 CASE_APPEND_ENUM(ANDROID_CONTROL_EFFECT_AQUA)
222 default: result.append("UNKNOWN\n");
223 }
224
225 result.append(" Antibanding mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700226 switch (p.antibandingMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700227 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_AUTO)
228 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_OFF)
229 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_50HZ)
230 CASE_APPEND_ENUM(ANDROID_CONTROL_AE_ANTIBANDING_60HZ)
231 default: result.append("UNKNOWN\n");
232 }
233
234 result.append(" Scene mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700235 switch (p.sceneMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700236 case ANDROID_CONTROL_SCENE_MODE_UNSUPPORTED:
237 result.append("AUTO\n"); break;
238 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_ACTION)
239 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_PORTRAIT)
240 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_LANDSCAPE)
241 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_NIGHT)
242 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_NIGHT_PORTRAIT)
243 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_THEATRE)
244 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_BEACH)
245 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SNOW)
246 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SUNSET)
247 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_STEADYPHOTO)
248 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_FIREWORKS)
249 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_SPORTS)
250 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_PARTY)
251 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_CANDLELIGHT)
252 CASE_APPEND_ENUM(ANDROID_CONTROL_SCENE_MODE_BARCODE)
253 default: result.append("UNKNOWN\n");
254 }
255
256 result.append(" Flash mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700257 switch (p.flashMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700258 CASE_APPEND_ENUM(Parameters::FLASH_MODE_OFF)
259 CASE_APPEND_ENUM(Parameters::FLASH_MODE_AUTO)
260 CASE_APPEND_ENUM(Parameters::FLASH_MODE_ON)
261 CASE_APPEND_ENUM(Parameters::FLASH_MODE_TORCH)
262 CASE_APPEND_ENUM(Parameters::FLASH_MODE_RED_EYE)
263 CASE_APPEND_ENUM(Parameters::FLASH_MODE_INVALID)
264 default: result.append("UNKNOWN\n");
265 }
266
267 result.append(" Focus mode: ");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700268 switch (p.focusMode) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700269 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_AUTO)
270 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_MACRO)
271 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_CONTINUOUS_VIDEO)
272 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_CONTINUOUS_PICTURE)
273 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_EDOF)
274 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_INFINITY)
275 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_FIXED)
276 CASE_APPEND_ENUM(Parameters::FOCUS_MODE_INVALID)
277 default: result.append("UNKNOWN\n");
278 }
279
280 result.append(" Focusing areas:\n");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700281 for (size_t i = 0; i < p.focusingAreas.size(); i++) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700282 result.appendFormat(" [ (%d, %d, %d, %d), weight %d ]\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700283 p.focusingAreas[i].left,
284 p.focusingAreas[i].top,
285 p.focusingAreas[i].right,
286 p.focusingAreas[i].bottom,
287 p.focusingAreas[i].weight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700288 }
289
290 result.appendFormat(" Exposure compensation index: %d\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700291 p.exposureCompensation);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700292
293 result.appendFormat(" AE lock %s, AWB lock %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700294 p.autoExposureLock ? "enabled" : "disabled",
295 p.autoWhiteBalanceLock ? "enabled" : "disabled" );
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700296
297 result.appendFormat(" Metering areas:\n");
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700298 for (size_t i = 0; i < p.meteringAreas.size(); i++) {
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700299 result.appendFormat(" [ (%d, %d, %d, %d), weight %d ]\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700300 p.meteringAreas[i].left,
301 p.meteringAreas[i].top,
302 p.meteringAreas[i].right,
303 p.meteringAreas[i].bottom,
304 p.meteringAreas[i].weight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700305 }
306
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700307 result.appendFormat(" Zoom index: %d\n", p.zoom);
308 result.appendFormat(" Video size: %d x %d\n", p.videoWidth,
309 p.videoHeight);
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700310
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700311 result.appendFormat(" Recording hint is %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700312 p.recordingHint ? "set" : "not set");
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700313
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700314 result.appendFormat(" Video stabilization is %s\n",
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -0700315 p.videoStabilization ? "enabled" : "disabled");
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700316
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700317 result.append(" Current streams:\n");
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700318 result.appendFormat(" Preview stream ID: %d\n",
319 getPreviewStreamId());
Eino-Ville Talvala177bd342012-08-28 01:25:43 -0700320 result.appendFormat(" Capture stream ID: %d\n",
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700321 getCaptureStreamId());
322 result.appendFormat(" Recording stream ID: %d\n",
323 getRecordingStreamId());
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700324
325 result.append(" Current requests:\n");
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700326 if (mPreviewRequest.entryCount() != 0) {
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700327 result.append(" Preview request:\n");
328 write(fd, result.string(), result.size());
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700329 mPreviewRequest.dump(fd, 2, 6);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700330 } else {
331 result.append(" Preview request: undefined\n");
332 write(fd, result.string(), result.size());
333 }
334
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700335 if (mRecordingRequest.entryCount() != 0) {
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700336 result = " Recording request:\n";
337 write(fd, result.string(), result.size());
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700338 mRecordingRequest.dump(fd, 2, 6);
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700339 } else {
340 result = " Recording request: undefined\n";
341 write(fd, result.string(), result.size());
342 }
343
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700344 mCaptureSequencer->dump(fd, args);
345
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -0700346 mFrameProcessor->dump(fd, args);
347
Eino-Ville Talvala22745492012-09-17 17:55:07 -0700348 mZslProcessor->dump(fd, args);
349
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700350 result = " Device dump:\n";
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700351 write(fd, result.string(), result.size());
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700352
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700353 status_t res = mDevice->dump(fd, args);
354 if (res != OK) {
355 result = String8::format(" Error dumping device: %s (%d)",
356 strerror(-res), res);
357 write(fd, result.string(), result.size());
358 }
Eino-Ville Talvala7f610842012-06-07 10:20:51 -0700359
360#undef CASE_APPEND_ENUM
Eino-Ville Talvala611f6192012-05-31 12:28:23 -0700361 return NO_ERROR;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700362}
363
364// ICamera interface
365
366void Camera2Client::disconnect() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700367 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700368 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700369 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700370 status_t res;
371 if ( (res = checkPid(__FUNCTION__) ) != OK) return;
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700372
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700373 if (mDevice == 0) return;
374
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700375 stopPreviewL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700376
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700377 if (mPreviewStreamId != NO_STREAM) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700378 mDevice->deleteStream(mPreviewStreamId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700379 mPreviewStreamId = NO_STREAM;
380 }
381
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700382 mJpegProcessor->deleteStream();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700383
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -0700384 if (mRecordingStreamId != NO_STREAM) {
385 mDevice->deleteStream(mRecordingStreamId);
386 mRecordingStreamId = NO_STREAM;
387 }
388
Eino-Ville Talvala28639182012-08-28 11:34:14 -0700389 mCallbackProcessor->deleteStream();
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700390
Eino-Ville Talvala7d8b92b2012-09-05 19:02:43 -0700391 mZslProcessor->deleteStream();
392
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700393 mDevice.clear();
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700394 SharedParameters::Lock l(mParameters);
395 l.mParameters.state = Parameters::DISCONNECTED;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700396
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700397 CameraService::Client::disconnect();
398}
399
400status_t Camera2Client::connect(const sp<ICameraClient>& client) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700401 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700402 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700403 Mutex::Autolock icl(mICameraLock);
404
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700405 if (mClientPid != 0 && getCallingPid() != mClientPid) {
406 ALOGE("%s: Camera %d: Connection attempt from pid %d; "
407 "current locked to pid %d", __FUNCTION__,
408 mCameraId, getCallingPid(), mClientPid);
409 return BAD_VALUE;
410 }
411
412 mClientPid = getCallingPid();
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700413
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700414 mCameraClient = client;
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -0700415 mSharedCameraClient = client;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700416
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700417 SharedParameters::Lock l(mParameters);
418 l.mParameters.state = Parameters::STOPPED;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700419
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700420 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700421}
422
423status_t Camera2Client::lock() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700424 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700425 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700426 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700427 ALOGV("%s: Camera %d: Lock call from pid %d; current client pid %d",
428 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700429
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700430 if (mClientPid == 0) {
431 mClientPid = getCallingPid();
432 return OK;
433 }
434
435 if (mClientPid != getCallingPid()) {
436 ALOGE("%s: Camera %d: Lock call from pid %d; currently locked to pid %d",
437 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
438 return EBUSY;
439 }
440
441 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700442}
443
444status_t Camera2Client::unlock() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700445 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700446 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700447 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700448 ALOGV("%s: Camera %d: Unlock call from pid %d; current client pid %d",
449 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700450
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700451 // TODO: Check for uninterruptable conditions
452
453 if (mClientPid == getCallingPid()) {
454 mClientPid = 0;
455 mCameraClient.clear();
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -0700456 mSharedCameraClient.clear();
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700457 return OK;
458 }
459
460 ALOGE("%s: Camera %d: Unlock call from pid %d; currently locked to pid %d",
461 __FUNCTION__, mCameraId, getCallingPid(), mClientPid);
462 return EBUSY;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700463}
464
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700465status_t Camera2Client::setPreviewDisplay(
466 const sp<Surface>& surface) {
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 (surface != 0) {
476 binder = surface->asBinder();
477 window = surface;
478 }
479
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700480 return setPreviewWindowL(binder,window);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700481}
482
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700483status_t Camera2Client::setPreviewTexture(
484 const sp<ISurfaceTexture>& surfaceTexture) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700485 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700486 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700487 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700488 status_t res;
489 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700490
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700491 sp<IBinder> binder;
492 sp<ANativeWindow> window;
493 if (surfaceTexture != 0) {
494 binder = surfaceTexture->asBinder();
495 window = new SurfaceTextureClient(surfaceTexture);
496 }
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700497 return setPreviewWindowL(binder, window);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700498}
499
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700500status_t Camera2Client::setPreviewWindowL(const sp<IBinder>& binder,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700501 sp<ANativeWindow> window) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700502 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700503 status_t res;
504
505 if (binder == mPreviewSurface) {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700506 ALOGV("%s: Camera %d: New window is same as old window",
507 __FUNCTION__, mCameraId);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700508 return NO_ERROR;
509 }
510
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700511 SharedParameters::Lock l(mParameters);
512 switch (l.mParameters.state) {
513 case Parameters::DISCONNECTED:
514 case Parameters::RECORD:
515 case Parameters::STILL_CAPTURE:
516 case Parameters::VIDEO_SNAPSHOT:
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700517 ALOGE("%s: Camera %d: Cannot set preview display while in state %s",
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700518 __FUNCTION__, mCameraId,
519 Parameters::getStateName(l.mParameters.state));
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700520 return INVALID_OPERATION;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700521 case Parameters::STOPPED:
522 case Parameters::WAITING_FOR_PREVIEW_WINDOW:
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700523 // OK
524 break;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700525 case Parameters::PREVIEW:
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700526 // Already running preview - need to stop and create a new stream
527 // TODO: Optimize this so that we don't wait for old stream to drain
528 // before spinning up new stream
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700529 mDevice->clearStreamingRequest();
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700530 l.mParameters.state = Parameters::WAITING_FOR_PREVIEW_WINDOW;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700531 break;
532 }
533
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700534 if (mPreviewStreamId != NO_STREAM) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700535 res = mDevice->waitUntilDrained();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700536 if (res != OK) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700537 ALOGE("%s: Error waiting for preview to drain: %s (%d)",
538 __FUNCTION__, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700539 return res;
540 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700541 res = mDevice->deleteStream(mPreviewStreamId);
542 if (res != OK) {
543 ALOGE("%s: Unable to delete old preview stream: %s (%d)",
544 __FUNCTION__, strerror(-res), res);
545 return res;
546 }
547 mPreviewStreamId = NO_STREAM;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700548 }
549
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700550 mPreviewSurface = binder;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700551 mPreviewWindow = window;
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700552
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700553 if (l.mParameters.state == Parameters::WAITING_FOR_PREVIEW_WINDOW) {
554 return startPreviewL(l.mParameters, false);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700555 }
556
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700557 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700558}
559
560void Camera2Client::setPreviewCallbackFlag(int flag) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700561 ATRACE_CALL();
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700562 ALOGV("%s: Camera %d: Flag 0x%x", __FUNCTION__, mCameraId, flag);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700563 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700564 status_t res;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700565 if ( checkPid(__FUNCTION__) != OK) return;
566
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700567 SharedParameters::Lock l(mParameters);
568 setPreviewCallbackFlagL(l.mParameters, flag);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700569}
570
571void Camera2Client::setPreviewCallbackFlagL(Parameters &params, int flag) {
572 status_t res = OK;
573 if (flag & CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) {
574 ALOGV("%s: setting oneshot", __FUNCTION__);
575 params.previewCallbackOneShot = true;
576 }
577 if (params.previewCallbackFlags != (uint32_t)flag) {
578 params.previewCallbackFlags = flag;
579 switch(params.state) {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700580 case Parameters::PREVIEW:
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700581 res = startPreviewL(params, true);
582 break;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700583 case Parameters::RECORD:
584 case Parameters::VIDEO_SNAPSHOT:
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700585 res = startRecordingL(params, true);
586 break;
587 default:
588 break;
589 }
590 if (res != OK) {
591 ALOGE("%s: Camera %d: Unable to refresh request in state %s",
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700592 __FUNCTION__, mCameraId,
593 Parameters::getStateName(params.state));
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700594 }
595 }
596
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700597}
598
599status_t Camera2Client::startPreview() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700600 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700601 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700602 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700603 status_t res;
604 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700605 SharedParameters::Lock l(mParameters);
606 return startPreviewL(l.mParameters, false);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700607}
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700608
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700609status_t Camera2Client::startPreviewL(Parameters &params, bool restart) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700610 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700611 status_t res;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700612 if (params.state >= Parameters::PREVIEW && !restart) {
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700613 ALOGE("%s: Can't start preview in state %s",
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700614 __FUNCTION__,
615 Parameters::getStateName(params.state));
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700616 return INVALID_OPERATION;
617 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700618
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700619 if (mPreviewWindow == 0) {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700620 params.state = Parameters::WAITING_FOR_PREVIEW_WINDOW;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700621 return OK;
622 }
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700623 params.state = Parameters::STOPPED;
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700624
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700625 res = updatePreviewStream(params);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700626 if (res != OK) {
627 ALOGE("%s: Camera %d: Unable to update preview stream: %s (%d)",
628 __FUNCTION__, mCameraId, strerror(-res), res);
629 return res;
630 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700631 bool callbacksEnabled = params.previewCallbackFlags &
632 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK;
633 if (callbacksEnabled) {
Eino-Ville Talvala28639182012-08-28 11:34:14 -0700634 res = mCallbackProcessor->updateStream(params);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700635 if (res != OK) {
636 ALOGE("%s: Camera %d: Unable to update callback stream: %s (%d)",
637 __FUNCTION__, mCameraId, strerror(-res), res);
638 return res;
639 }
640 }
Eino-Ville Talvalaf98cbbe2012-08-29 18:06:32 -0700641 if (params.zslMode && !params.recordingHint) {
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700642 res = mZslProcessor->updateStream(params);
643 if (res != OK) {
644 ALOGE("%s: Camera %d: Unable to update ZSL stream: %s (%d)",
645 __FUNCTION__, mCameraId, strerror(-res), res);
646 return res;
647 }
648 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700649
Eino-Ville Talvalaf98cbbe2012-08-29 18:06:32 -0700650 CameraMetadata *request;
651 if (!params.recordingHint) {
652 if (mPreviewRequest.entryCount() == 0) {
653 res = updatePreviewRequest(params);
654 if (res != OK) {
655 ALOGE("%s: Camera %d: Unable to create preview request: %s (%d)",
656 __FUNCTION__, mCameraId, strerror(-res), res);
657 return res;
658 }
659 }
660 request = &mPreviewRequest;
661 } else {
662 // With recording hint set, we're going to be operating under the
663 // assumption that the user will record video. To optimize recording
664 // startup time, create the necessary output streams for recording and
665 // video snapshot now if they don't already exist.
666 if (mRecordingRequest.entryCount() == 0) {
667 res = updateRecordingRequest(params);
668 if (res != OK) {
669 ALOGE("%s: Camera %d: Unable to create recording preview "
670 "request: %s (%d)",
671 __FUNCTION__, mCameraId, strerror(-res), res);
672 return res;
673 }
674 }
675 request = &mRecordingRequest;
676
Eino-Ville Talvala587879f2012-09-10 16:07:03 -0700677 // TODO: Re-enable recording stream creation/update here once issues are
678 // resolved
Eino-Ville Talvalaf98cbbe2012-08-29 18:06:32 -0700679
680 res = mJpegProcessor->updateStream(params);
681 if (res != OK) {
682 ALOGE("%s: Camera %d: Can't pre-configure still image "
683 "stream: %s (%d)",
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700684 __FUNCTION__, mCameraId, strerror(-res), res);
685 return res;
686 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700687 }
688
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700689 Vector<uint8_t> outputStreams;
690 outputStreams.push(getPreviewStreamId());
691
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700692 if (callbacksEnabled) {
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700693 outputStreams.push(getCallbackStreamId());
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700694 }
Eino-Ville Talvalaf98cbbe2012-08-29 18:06:32 -0700695 if (params.zslMode && !params.recordingHint) {
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700696 outputStreams.push(getZslStreamId());
697 }
698
Eino-Ville Talvalaf98cbbe2012-08-29 18:06:32 -0700699 res = request->update(
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700700 ANDROID_REQUEST_OUTPUT_STREAMS,
701 outputStreams);
702
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700703 if (res != OK) {
704 ALOGE("%s: Camera %d: Unable to set up preview request: %s (%d)",
705 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700706 return res;
707 }
Eino-Ville Talvalaf98cbbe2012-08-29 18:06:32 -0700708 res = request->sort();
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -0700709 if (res != OK) {
710 ALOGE("%s: Camera %d: Error sorting preview request: %s (%d)",
711 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700712 return res;
713 }
714
Eino-Ville Talvalaf98cbbe2012-08-29 18:06:32 -0700715 res = mDevice->setStreamingRequest(*request);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700716 if (res != OK) {
Eino-Ville Talvalabd47b7b2012-06-07 10:34:20 -0700717 ALOGE("%s: Camera %d: Unable to set preview request to start preview: "
718 "%s (%d)",
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700719 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700720 return res;
721 }
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700722 params.state = Parameters::PREVIEW;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700723
724 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700725}
726
727void Camera2Client::stopPreview() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700728 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700729 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700730 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700731 status_t res;
732 if ( (res = checkPid(__FUNCTION__) ) != OK) return;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700733 stopPreviewL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700734}
735
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -0700736void Camera2Client::stopPreviewL() {
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700737 ATRACE_CALL();
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700738 Parameters::State state;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700739 {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700740 SharedParameters::Lock l(mParameters);
741 state = l.mParameters.state;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700742 }
743
744 switch (state) {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700745 case Parameters::DISCONNECTED:
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700746 ALOGE("%s: Camera %d: Call before initialized",
747 __FUNCTION__, mCameraId);
748 break;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700749 case Parameters::STOPPED:
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700750 break;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700751 case Parameters::STILL_CAPTURE:
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700752 ALOGE("%s: Camera %d: Cannot stop preview during still capture.",
753 __FUNCTION__, mCameraId);
754 break;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700755 case Parameters::RECORD:
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700756 // no break - identical to preview
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700757 case Parameters::PREVIEW:
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700758 mDevice->clearStreamingRequest();
Eino-Ville Talvala22671062012-07-20 18:30:37 -0700759 mDevice->waitUntilDrained();
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700760 // no break
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700761 case Parameters::WAITING_FOR_PREVIEW_WINDOW: {
762 SharedParameters::Lock l(mParameters);
763 l.mParameters.state = Parameters::STOPPED;
764 commandStopFaceDetectionL(l.mParameters);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700765 break;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700766 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700767 default:
768 ALOGE("%s: Camera %d: Unknown state %d", __FUNCTION__, mCameraId,
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700769 state);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700770 }
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700771}
772
773bool Camera2Client::previewEnabled() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700774 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700775 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700776 status_t res;
777 if ( (res = checkPid(__FUNCTION__) ) != OK) return false;
778
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700779 SharedParameters::Lock l(mParameters);
780 return l.mParameters.state == Parameters::PREVIEW;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700781}
782
783status_t Camera2Client::storeMetaDataInBuffers(bool enabled) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700784 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700785 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700786 status_t res;
787 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
788
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700789 SharedParameters::Lock l(mParameters);
790 switch (l.mParameters.state) {
791 case Parameters::RECORD:
792 case Parameters::VIDEO_SNAPSHOT:
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700793 ALOGE("%s: Camera %d: Can't be called in state %s",
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700794 __FUNCTION__, mCameraId,
795 Parameters::getStateName(l.mParameters.state));
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700796 return INVALID_OPERATION;
797 default:
798 // OK
799 break;
800 }
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700801
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700802 l.mParameters.storeMetadataInBuffers = enabled;
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700803
804 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700805}
806
807status_t Camera2Client::startRecording() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700808 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700809 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700810 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700811 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700812 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700813 SharedParameters::Lock l(mParameters);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700814
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700815 return startRecordingL(l.mParameters, false);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700816}
817
818status_t Camera2Client::startRecordingL(Parameters &params, bool restart) {
819 status_t res;
820 switch (params.state) {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700821 case Parameters::STOPPED:
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700822 res = startPreviewL(params, false);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700823 if (res != OK) return res;
824 break;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700825 case Parameters::PREVIEW:
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700826 // Ready to go
827 break;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700828 case Parameters::RECORD:
829 case Parameters::VIDEO_SNAPSHOT:
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700830 // OK to call this when recording is already on, just skip unless
831 // we're looking to restart
832 if (!restart) return OK;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700833 break;
834 default:
835 ALOGE("%s: Camera %d: Can't start recording in state %s",
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700836 __FUNCTION__, mCameraId,
837 Parameters::getStateName(params.state));
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700838 return INVALID_OPERATION;
839 };
840
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700841 if (!params.storeMetadataInBuffers) {
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700842 ALOGE("%s: Camera %d: Recording only supported in metadata mode, but "
843 "non-metadata recording mode requested!", __FUNCTION__,
844 mCameraId);
845 return INVALID_OPERATION;
846 }
847
Eino-Ville Talvala33578832012-09-06 18:26:58 -0700848 mCameraService->playSound(CameraService::SOUND_RECORDING);
849
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700850 res = updateRecordingStream(params);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700851 if (res != OK) {
852 ALOGE("%s: Camera %d: Unable to update recording stream: %s (%d)",
853 __FUNCTION__, mCameraId, strerror(-res), res);
854 return res;
855 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700856 bool callbacksEnabled = params.previewCallbackFlags &
857 CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK;
858 if (callbacksEnabled) {
Eino-Ville Talvala28639182012-08-28 11:34:14 -0700859 res = mCallbackProcessor->updateStream(params);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700860 if (res != OK) {
861 ALOGE("%s: Camera %d: Unable to update callback stream: %s (%d)",
862 __FUNCTION__, mCameraId, strerror(-res), res);
863 return res;
864 }
865 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700866
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700867 if (mRecordingRequest.entryCount() == 0) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700868 res = updateRecordingRequest(params);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700869 if (res != OK) {
870 ALOGE("%s: Camera %d: Unable to create recording request: %s (%d)",
871 __FUNCTION__, mCameraId, strerror(-res), res);
872 return res;
873 }
874 }
875
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700876 if (callbacksEnabled) {
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700877 uint8_t outputStreams[3] ={
878 getPreviewStreamId(),
879 getRecordingStreamId(),
880 getCallbackStreamId()
881 };
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700882 res = mRecordingRequest.update(
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700883 ANDROID_REQUEST_OUTPUT_STREAMS,
884 outputStreams, 3);
885 } else {
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700886 uint8_t outputStreams[2] = {
887 getPreviewStreamId(),
888 getRecordingStreamId()
889 };
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700890 res = mRecordingRequest.update(
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700891 ANDROID_REQUEST_OUTPUT_STREAMS,
892 outputStreams, 2);
893 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700894 if (res != OK) {
895 ALOGE("%s: Camera %d: Unable to set up recording request: %s (%d)",
896 __FUNCTION__, mCameraId, strerror(-res), res);
897 return res;
898 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700899 res = mRecordingRequest.sort();
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700900 if (res != OK) {
901 ALOGE("%s: Camera %d: Error sorting recording request: %s (%d)",
902 __FUNCTION__, mCameraId, strerror(-res), res);
903 return res;
904 }
905
906 res = mDevice->setStreamingRequest(mRecordingRequest);
907 if (res != OK) {
908 ALOGE("%s: Camera %d: Unable to set recording request to start "
909 "recording: %s (%d)", __FUNCTION__, mCameraId,
910 strerror(-res), res);
911 return res;
912 }
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700913 if (params.state < Parameters::RECORD) {
914 params.state = Parameters::RECORD;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700915 }
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700916
917 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700918}
919
920void Camera2Client::stopRecording() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700921 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700922 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700923 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700924 SharedParameters::Lock l(mParameters);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -0700925
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700926 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700927 if ( (res = checkPid(__FUNCTION__) ) != OK) return;
928
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700929 switch (l.mParameters.state) {
930 case Parameters::RECORD:
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700931 // OK to stop
932 break;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700933 case Parameters::STOPPED:
934 case Parameters::PREVIEW:
935 case Parameters::STILL_CAPTURE:
936 case Parameters::VIDEO_SNAPSHOT:
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700937 default:
938 ALOGE("%s: Camera %d: Can't stop recording in state %s",
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700939 __FUNCTION__, mCameraId,
940 Parameters::getStateName(l.mParameters.state));
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700941 return;
942 };
943
Eino-Ville Talvala33578832012-09-06 18:26:58 -0700944 mCameraService->playSound(CameraService::SOUND_RECORDING);
945
Eino-Ville Talvalaf98cbbe2012-08-29 18:06:32 -0700946 res = startPreviewL(l.mParameters, true);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700947 if (res != OK) {
Eino-Ville Talvalaf98cbbe2012-08-29 18:06:32 -0700948 ALOGE("%s: Camera %d: Unable to return to preview",
949 __FUNCTION__, mCameraId);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700950 }
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700951}
952
953bool Camera2Client::recordingEnabled() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700954 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700955 Mutex::Autolock icl(mICameraLock);
James Dong8da4cd72012-08-04 19:58:07 -0700956
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700957 if ( checkPid(__FUNCTION__) != OK) return false;
958
James Dong8da4cd72012-08-04 19:58:07 -0700959 return recordingEnabledL();
960}
961
962bool Camera2Client::recordingEnabledL() {
963 ATRACE_CALL();
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700964 SharedParameters::Lock l(mParameters);
James Dong8da4cd72012-08-04 19:58:07 -0700965
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700966 return (l.mParameters.state == Parameters::RECORD
967 || l.mParameters.state == Parameters::VIDEO_SNAPSHOT);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700968}
969
970void Camera2Client::releaseRecordingFrame(const sp<IMemory>& mem) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -0700971 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -0700972 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -0700973 status_t res;
974 if ( checkPid(__FUNCTION__) != OK) return;
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -0700975
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700976 SharedParameters::Lock l(mParameters);
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -0700977
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700978 // Make sure this is for the current heap
979 ssize_t offset;
980 size_t size;
981 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
982 if (heap->getHeapID() != mRecordingHeap->mHeap->getHeapID()) {
983 ALOGW("%s: Camera %d: Mismatched heap ID, ignoring release "
984 "(got %x, expected %x)", __FUNCTION__, mCameraId,
985 heap->getHeapID(), mRecordingHeap->mHeap->getHeapID());
986 return;
987 }
Eino-Ville Talvala78822d72012-07-18 17:52:18 -0700988 uint8_t *data = (uint8_t*)heap->getBase() + offset;
989 uint32_t type = *(uint32_t*)data;
990 if (type != kMetadataBufferTypeGrallocSource) {
991 ALOGE("%s: Camera %d: Recording frame type invalid (got %x, expected %x)",
992 __FUNCTION__, mCameraId, type, kMetadataBufferTypeGrallocSource);
993 return;
994 }
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -0700995
996 // Release the buffer back to the recording queue
997
998 buffer_handle_t imgHandle = *(buffer_handle_t*)(data + 4);
999
1000 size_t itemIndex;
1001 for (itemIndex = 0; itemIndex < mRecordingBuffers.size(); itemIndex++) {
1002 const BufferItemConsumer::BufferItem item = mRecordingBuffers[itemIndex];
1003 if (item.mBuf != BufferItemConsumer::INVALID_BUFFER_SLOT &&
1004 item.mGraphicBuffer->handle == imgHandle) {
1005 break;
1006 }
1007 }
1008 if (itemIndex == mRecordingBuffers.size()) {
1009 ALOGE("%s: Camera %d: Can't find buffer_handle_t %p in list of "
1010 "outstanding buffers", __FUNCTION__, mCameraId, imgHandle);
1011 return;
1012 }
1013
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001014 ALOGV("%s: Camera %d: Freeing buffer_handle_t %p", __FUNCTION__, mCameraId,
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07001015 imgHandle);
1016
1017 res = mRecordingConsumer->releaseBuffer(mRecordingBuffers[itemIndex]);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001018 if (res != OK) {
1019 ALOGE("%s: Camera %d: Unable to free recording frame (buffer_handle_t: %p):"
1020 "%s (%d)",
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07001021 __FUNCTION__, mCameraId, imgHandle, strerror(-res), res);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001022 return;
1023 }
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07001024 mRecordingBuffers.replaceAt(itemIndex);
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001025
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001026 mRecordingHeapFree++;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001027}
1028
1029status_t Camera2Client::autoFocus() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001030 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001031 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001032 status_t res;
1033 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
1034
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001035 int triggerId;
1036 {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001037 SharedParameters::Lock l(mParameters);
1038 l.mParameters.currentAfTriggerId = ++l.mParameters.afTriggerCounter;
1039 triggerId = l.mParameters.currentAfTriggerId;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001040 }
1041
1042 mDevice->triggerAutofocus(triggerId);
1043
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001044 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001045}
1046
1047status_t Camera2Client::cancelAutoFocus() {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001048 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001049 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001050 status_t res;
1051 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
1052
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001053 int triggerId;
1054 {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001055 SharedParameters::Lock l(mParameters);
1056 triggerId = ++l.mParameters.afTriggerCounter;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001057 }
1058
1059 mDevice->triggerCancelAutofocus(triggerId);
1060
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001061 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001062}
1063
1064status_t Camera2Client::takePicture(int msgType) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001065 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001066 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001067 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001068 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001069
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001070 SharedParameters::Lock l(mParameters);
1071 switch (l.mParameters.state) {
1072 case Parameters::DISCONNECTED:
1073 case Parameters::STOPPED:
1074 case Parameters::WAITING_FOR_PREVIEW_WINDOW:
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001075 ALOGE("%s: Camera %d: Cannot take picture without preview enabled",
1076 __FUNCTION__, mCameraId);
1077 return INVALID_OPERATION;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001078 case Parameters::PREVIEW:
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001079 // Good to go for takePicture
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001080 res = commandStopFaceDetectionL(l.mParameters);
1081 if (res != OK) {
1082 ALOGE("%s: Camera %d: Unable to stop face detection for still capture",
1083 __FUNCTION__, mCameraId);
1084 return res;
1085 }
1086 l.mParameters.state = Parameters::STILL_CAPTURE;
1087 break;
1088 case Parameters::RECORD:
1089 // Good to go for video snapshot
1090 l.mParameters.state = Parameters::VIDEO_SNAPSHOT;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001091 break;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001092 case Parameters::STILL_CAPTURE:
1093 case Parameters::VIDEO_SNAPSHOT:
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001094 ALOGE("%s: Camera %d: Already taking a picture",
1095 __FUNCTION__, mCameraId);
1096 return INVALID_OPERATION;
1097 }
1098
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001099 ALOGV("%s: Camera %d: Starting picture capture", __FUNCTION__, mCameraId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001100
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001101 res = mJpegProcessor->updateStream(l.mParameters);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001102 if (res != OK) {
1103 ALOGE("%s: Camera %d: Can't set up still image stream: %s (%d)",
1104 __FUNCTION__, mCameraId, strerror(-res), res);
1105 return res;
1106 }
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001107
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001108 res = mCaptureSequencer->startCapture();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001109 if (res != OK) {
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001110 ALOGE("%s: Camera %d: Unable to start capture: %s (%d)",
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001111 __FUNCTION__, mCameraId, strerror(-res), res);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001112 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001113
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001114 return res;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001115}
1116
1117status_t Camera2Client::setParameters(const String8& params) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001118 ATRACE_CALL();
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -07001119 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001120 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001121 status_t res;
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001122 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
1123
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001124 SharedParameters::Lock l(mParameters);
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001125
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001126 res = l.mParameters.set(params);
1127 if (res != OK) return res;
Eino-Ville Talvala6861a4e2012-06-07 10:32:12 -07001128
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001129 res = updateRequests(l.mParameters);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001130
1131 return res;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001132}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001133
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001134String8 Camera2Client::getParameters() const {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001135 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001136 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001137 if ( checkPid(__FUNCTION__) != OK) return String8();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001138
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001139 SharedParameters::ReadLock l(mParameters);
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001140
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001141 // TODO: Deal with focus distances
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001142 return l.mParameters.paramsFlattened;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001143}
1144
1145status_t Camera2Client::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001146 ATRACE_CALL();
Eino-Ville Talvalaac45eb32012-06-07 10:24:51 -07001147 Mutex::Autolock icl(mICameraLock);
Eino-Ville Talvala3a609142012-07-31 14:36:26 -07001148 status_t res;
1149 if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001150
1151 ALOGV("%s: Camera %d: Command %d (%d, %d)", __FUNCTION__, mCameraId,
1152 cmd, arg1, arg2);
1153
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001154 switch (cmd) {
1155 case CAMERA_CMD_START_SMOOTH_ZOOM:
1156 return commandStartSmoothZoomL();
1157 case CAMERA_CMD_STOP_SMOOTH_ZOOM:
1158 return commandStopSmoothZoomL();
1159 case CAMERA_CMD_SET_DISPLAY_ORIENTATION:
1160 return commandSetDisplayOrientationL(arg1);
1161 case CAMERA_CMD_ENABLE_SHUTTER_SOUND:
1162 return commandEnableShutterSoundL(arg1 == 1);
1163 case CAMERA_CMD_PLAY_RECORDING_SOUND:
1164 return commandPlayRecordingSoundL();
1165 case CAMERA_CMD_START_FACE_DETECTION:
1166 return commandStartFaceDetectionL(arg1);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001167 case CAMERA_CMD_STOP_FACE_DETECTION: {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001168 SharedParameters::Lock l(mParameters);
1169 return commandStopFaceDetectionL(l.mParameters);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001170 }
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001171 case CAMERA_CMD_ENABLE_FOCUS_MOVE_MSG:
1172 return commandEnableFocusMoveMsgL(arg1 == 1);
1173 case CAMERA_CMD_PING:
1174 return commandPingL();
1175 case CAMERA_CMD_SET_VIDEO_BUFFER_COUNT:
1176 return commandSetVideoBufferCountL(arg1);
1177 default:
1178 ALOGE("%s: Unknown command %d (arguments %d, %d)",
1179 __FUNCTION__, cmd, arg1, arg2);
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001180 return BAD_VALUE;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001181 }
1182}
James Dong983cf232012-08-01 16:39:55 -07001183
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001184status_t Camera2Client::commandStartSmoothZoomL() {
1185 ALOGE("%s: Unimplemented!", __FUNCTION__);
1186 return OK;
1187}
James Dong983cf232012-08-01 16:39:55 -07001188
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001189status_t Camera2Client::commandStopSmoothZoomL() {
1190 ALOGE("%s: Unimplemented!", __FUNCTION__);
1191 return OK;
1192}
James Dong983cf232012-08-01 16:39:55 -07001193
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001194status_t Camera2Client::commandSetDisplayOrientationL(int degrees) {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001195 int transform = Parameters::degToTransform(degrees,
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001196 mCameraFacing == CAMERA_FACING_FRONT);
1197 if (transform == -1) {
1198 ALOGE("%s: Camera %d: Error setting %d as display orientation value",
1199 __FUNCTION__, mCameraId, degrees);
1200 return BAD_VALUE;
1201 }
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001202 SharedParameters::Lock l(mParameters);
1203 if (transform != l.mParameters.previewTransform &&
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001204 mPreviewStreamId != NO_STREAM) {
1205 mDevice->setStreamTransform(mPreviewStreamId, transform);
1206 }
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001207 l.mParameters.previewTransform = transform;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001208 return OK;
1209}
1210
1211status_t Camera2Client::commandEnableShutterSoundL(bool enable) {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001212 SharedParameters::Lock l(mParameters);
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001213 if (enable) {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001214 l.mParameters.playShutterSound = true;
James Dong983cf232012-08-01 16:39:55 -07001215 return OK;
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001216 }
1217
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001218 // Disabling shutter sound may not be allowed. In that case only
1219 // allow the mediaserver process to disable the sound.
1220 char value[PROPERTY_VALUE_MAX];
1221 property_get("ro.camera.sound.forced", value, "0");
1222 if (strncmp(value, "0", 2) != 0) {
1223 // Disabling shutter sound is not allowed. Deny if the current
1224 // process is not mediaserver.
1225 if (getCallingPid() != getpid()) {
1226 ALOGE("Failed to disable shutter sound. Permission denied (pid %d)",
1227 getCallingPid());
1228 return PERMISSION_DENIED;
1229 }
1230 }
1231
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001232 l.mParameters.playShutterSound = false;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001233 return OK;
1234}
1235
1236status_t Camera2Client::commandPlayRecordingSoundL() {
1237 mCameraService->playSound(CameraService::SOUND_RECORDING);
1238 return OK;
1239}
1240
1241status_t Camera2Client::commandStartFaceDetectionL(int type) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001242 ALOGV("%s: Camera %d: Starting face detection",
1243 __FUNCTION__, mCameraId);
1244 status_t res;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001245 SharedParameters::Lock l(mParameters);
1246 switch (l.mParameters.state) {
1247 case Parameters::DISCONNECTED:
1248 case Parameters::STOPPED:
1249 case Parameters::WAITING_FOR_PREVIEW_WINDOW:
1250 case Parameters::STILL_CAPTURE:
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001251 ALOGE("%s: Camera %d: Cannot start face detection without preview active",
1252 __FUNCTION__, mCameraId);
1253 return INVALID_OPERATION;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001254 case Parameters::PREVIEW:
1255 case Parameters::RECORD:
1256 case Parameters::VIDEO_SNAPSHOT:
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001257 // Good to go for starting face detect
1258 break;
1259 }
1260 // Ignoring type
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001261 if (l.mParameters.fastInfo.bestFaceDetectMode ==
1262 ANDROID_STATS_FACE_DETECTION_OFF) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001263 ALOGE("%s: Camera %d: Face detection not supported",
1264 __FUNCTION__, mCameraId);
1265 return INVALID_OPERATION;
1266 }
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001267 if (l.mParameters.enableFaceDetect) return OK;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001268
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001269 l.mParameters.enableFaceDetect = true;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001270
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001271 res = updateRequests(l.mParameters);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001272
1273 return res;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001274}
1275
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001276status_t Camera2Client::commandStopFaceDetectionL(Parameters &params) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001277 status_t res = OK;
1278 ALOGV("%s: Camera %d: Stopping face detection",
1279 __FUNCTION__, mCameraId);
1280
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001281 if (!params.enableFaceDetect) return OK;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001282
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001283 params.enableFaceDetect = false;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001284
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001285 if (params.state == Parameters::PREVIEW
1286 || params.state == Parameters::RECORD
1287 || params.state == Parameters::VIDEO_SNAPSHOT) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001288 res = updateRequests(params);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001289 }
1290
1291 return res;
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001292}
1293
1294status_t Camera2Client::commandEnableFocusMoveMsgL(bool enable) {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001295 SharedParameters::Lock l(mParameters);
1296 l.mParameters.enableFocusMoveMessages = enable;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001297
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001298 return OK;
1299}
1300
1301status_t Camera2Client::commandPingL() {
1302 // Always ping back if access is proper and device is alive
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001303 SharedParameters::Lock l(mParameters);
1304 if (l.mParameters.state != Parameters::DISCONNECTED) {
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001305 return OK;
1306 } else {
1307 return NO_INIT;
1308 }
1309}
1310
1311status_t Camera2Client::commandSetVideoBufferCountL(size_t count) {
James Dong8da4cd72012-08-04 19:58:07 -07001312 if (recordingEnabledL()) {
Eino-Ville Talvala36cdfb12012-08-02 17:34:15 -07001313 ALOGE("%s: Camera %d: Error setting video buffer count after "
1314 "recording was started", __FUNCTION__, mCameraId);
1315 return INVALID_OPERATION;
1316 }
1317
1318 // 32 is the current upper limit on the video buffer count for BufferQueue
1319 if (count > 32) {
1320 ALOGE("%s: Camera %d: Error setting %d as video buffer count value",
1321 __FUNCTION__, mCameraId, count);
1322 return BAD_VALUE;
1323 }
1324
1325 // Need to reallocate memory for heap
1326 if (mRecordingHeapCount != count) {
1327 if (mRecordingHeap != 0) {
1328 mRecordingHeap.clear();
1329 mRecordingHeap = NULL;
1330 }
1331 mRecordingHeapCount = count;
1332 }
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001333
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001334 return OK;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001335}
1336
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001337/** Device-related methods */
1338
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -07001339void Camera2Client::notifyError(int errorCode, int arg1, int arg2) {
1340 ALOGE("Error condition %d reported by HAL, arguments %d, %d", errorCode, arg1, arg2);
1341}
1342
1343void Camera2Client::notifyShutter(int frameNumber, nsecs_t timestamp) {
1344 ALOGV("%s: Shutter notification for frame %d at time %lld", __FUNCTION__,
1345 frameNumber, timestamp);
1346}
1347
1348void Camera2Client::notifyAutoFocus(uint8_t newState, int triggerId) {
1349 ALOGV("%s: Autofocus state now %d, last trigger %d",
1350 __FUNCTION__, newState, triggerId);
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001351 bool sendCompletedMessage = false;
1352 bool sendMovingMessage = false;
1353
1354 bool success = false;
1355 bool afInMotion = false;
1356 {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001357 SharedParameters::Lock l(mParameters);
1358 switch (l.mParameters.focusMode) {
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001359 case Parameters::FOCUS_MODE_AUTO:
1360 case Parameters::FOCUS_MODE_MACRO:
1361 // Don't send notifications upstream if they're not for the current AF
1362 // trigger. For example, if cancel was called in between, or if we
1363 // already sent a notification about this AF call.
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001364 if (triggerId != l.mParameters.currentAfTriggerId) break;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001365 switch (newState) {
1366 case ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED:
1367 success = true;
1368 // no break
1369 case ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
1370 sendCompletedMessage = true;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001371 l.mParameters.currentAfTriggerId = -1;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001372 break;
1373 case ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN:
1374 // Just starting focusing, ignore
1375 break;
1376 case ANDROID_CONTROL_AF_STATE_INACTIVE:
1377 case ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN:
1378 case ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED:
1379 default:
1380 // Unexpected in AUTO/MACRO mode
1381 ALOGE("%s: Unexpected AF state transition in AUTO/MACRO mode: %d",
1382 __FUNCTION__, newState);
1383 break;
1384 }
1385 break;
1386 case Parameters::FOCUS_MODE_CONTINUOUS_VIDEO:
1387 case Parameters::FOCUS_MODE_CONTINUOUS_PICTURE:
1388 switch (newState) {
1389 case ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED:
1390 success = true;
1391 // no break
1392 case ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
1393 // Don't send notifications upstream if they're not for
1394 // the current AF trigger. For example, if cancel was
1395 // called in between, or if we already sent a
1396 // notification about this AF call.
1397 // Send both a 'AF done' callback and a 'AF move' callback
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001398 if (triggerId != l.mParameters.currentAfTriggerId) break;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001399 sendCompletedMessage = true;
1400 afInMotion = false;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001401 if (l.mParameters.enableFocusMoveMessages &&
1402 l.mParameters.afInMotion) {
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001403 sendMovingMessage = true;
1404 }
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001405 l.mParameters.currentAfTriggerId = -1;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001406 break;
1407 case ANDROID_CONTROL_AF_STATE_INACTIVE:
1408 // Cancel was called, or we switched state; care if
1409 // currently moving
1410 afInMotion = false;
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001411 if (l.mParameters.enableFocusMoveMessages &&
1412 l.mParameters.afInMotion) {
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001413 sendMovingMessage = true;
1414 }
1415 break;
1416 case ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN:
1417 // Start passive scan, inform upstream
1418 afInMotion = true;
1419 // no break
1420 case ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED:
1421 // Stop passive scan, inform upstream
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001422 if (l.mParameters.enableFocusMoveMessages) {
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001423 sendMovingMessage = true;
1424 }
1425 break;
1426 }
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001427 l.mParameters.afInMotion = afInMotion;
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001428 break;
1429 case Parameters::FOCUS_MODE_EDOF:
1430 case Parameters::FOCUS_MODE_INFINITY:
1431 case Parameters::FOCUS_MODE_FIXED:
1432 default:
1433 if (newState != ANDROID_CONTROL_AF_STATE_INACTIVE) {
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -07001434 ALOGE("%s: Unexpected AF state change %d "
1435 "(ID %d) in focus mode %d",
1436 __FUNCTION__, newState, triggerId,
1437 l.mParameters.focusMode);
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001438 }
1439 }
1440 }
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001441 if (sendMovingMessage) {
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -07001442 SharedCameraClient::Lock l(mSharedCameraClient);
1443 if (l.mCameraClient != 0) {
1444 l.mCameraClient->notifyCallback(CAMERA_MSG_FOCUS_MOVE,
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001445 afInMotion ? 1 : 0, 0);
1446 }
Eino-Ville Talvala174181e2012-08-03 13:53:39 -07001447 }
Eino-Ville Talvala603b12e2012-08-08 09:25:58 -07001448 if (sendCompletedMessage) {
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -07001449 SharedCameraClient::Lock l(mSharedCameraClient);
1450 if (l.mCameraClient != 0) {
1451 l.mCameraClient->notifyCallback(CAMERA_MSG_FOCUS,
1452 success ? 1 : 0, 0);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001453 }
Eino-Ville Talvala603b12e2012-08-08 09:25:58 -07001454 }
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -07001455}
1456
1457void Camera2Client::notifyAutoExposure(uint8_t newState, int triggerId) {
1458 ALOGV("%s: Autoexposure state now %d, last trigger %d",
1459 __FUNCTION__, newState, triggerId);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001460 mCaptureSequencer->notifyAutoExposure(newState, triggerId);
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -07001461}
1462
1463void Camera2Client::notifyAutoWhitebalance(uint8_t newState, int triggerId) {
1464 ALOGV("%s: Auto-whitebalance state now %d, last trigger %d",
1465 __FUNCTION__, newState, triggerId);
1466}
1467
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001468int Camera2Client::getCameraId() const {
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -07001469 return mCameraId;
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -07001470}
1471
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -07001472const sp<Camera2Device>& Camera2Client::getCameraDevice() {
1473 return mDevice;
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -07001474}
1475
Eino-Ville Talvala33578832012-09-06 18:26:58 -07001476const sp<CameraService>& Camera2Client::getCameraService() {
1477 return mCameraService;
1478}
1479
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -07001480camera2::SharedParameters& Camera2Client::getParameters() {
1481 return mParameters;
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -07001482}
1483
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001484int Camera2Client::getPreviewStreamId() const {
1485 return mPreviewStreamId;
1486}
1487
1488int Camera2Client::getCaptureStreamId() const {
1489 return mJpegProcessor->getStreamId();
1490}
1491
1492int Camera2Client::getCallbackStreamId() const {
1493 return mCallbackProcessor->getStreamId();
1494}
1495
1496int Camera2Client::getRecordingStreamId() const {
1497 return mRecordingStreamId;
1498}
1499
1500int Camera2Client::getZslStreamId() const {
1501 return mZslProcessor->getStreamId();
1502}
1503
1504status_t Camera2Client::registerFrameListener(int32_t id,
1505 wp<camera2::FrameProcessor::FilteredListener> listener) {
1506 return mFrameProcessor->registerListener(id, listener);
1507}
1508
1509status_t Camera2Client::removeFrameListener(int32_t id) {
1510 return mFrameProcessor->removeListener(id);
1511}
1512
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -07001513Camera2Client::SharedCameraClient::Lock::Lock(SharedCameraClient &client):
1514 mCameraClient(client.mCameraClient),
1515 mSharedClient(client) {
1516 mSharedClient.mCameraClientLock.lock();
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -07001517}
1518
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -07001519Camera2Client::SharedCameraClient::Lock::~Lock() {
1520 mSharedClient.mCameraClientLock.unlock();
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001521}
1522
Eino-Ville Talvala177bd342012-08-28 01:25:43 -07001523Camera2Client::SharedCameraClient::SharedCameraClient(const sp<ICameraClient>&client):
1524 mCameraClient(client) {
1525}
1526
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -07001527Camera2Client::SharedCameraClient& Camera2Client::SharedCameraClient::operator=(
1528 const sp<ICameraClient>&client) {
1529 Mutex::Autolock l(mCameraClientLock);
1530 mCameraClient = client;
1531 return *this;
1532}
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001533
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -07001534void Camera2Client::SharedCameraClient::clear() {
1535 Mutex::Autolock l(mCameraClientLock);
1536 mCameraClient.clear();
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001537}
1538
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001539const int32_t Camera2Client::kPreviewRequestId;
1540const int32_t Camera2Client::kRecordRequestId;
1541const int32_t Camera2Client::kFirstCaptureRequestId;
1542
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001543void Camera2Client::onRecordingFrameAvailable() {
1544 ATRACE_CALL();
1545 status_t res;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001546 sp<Camera2Heap> recordingHeap;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001547 size_t heapIdx = 0;
1548 nsecs_t timestamp;
1549 {
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001550 SharedParameters::Lock l(mParameters);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001551
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07001552 BufferItemConsumer::BufferItem imgBuffer;
1553 res = mRecordingConsumer->acquireBuffer(&imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001554 if (res != OK) {
1555 ALOGE("%s: Camera %d: Error receiving recording buffer: %s (%d)",
1556 __FUNCTION__, mCameraId, strerror(-res), res);
1557 return;
1558 }
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07001559 timestamp = imgBuffer.mTimestamp;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001560
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001561 mRecordingFrameCount++;
1562 ALOGV("OnRecordingFrame: Frame %d", mRecordingFrameCount);
1563
1564 // TODO: Signal errors here upstream
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001565 if (l.mParameters.state != Parameters::RECORD &&
1566 l.mParameters.state != Parameters::VIDEO_SNAPSHOT) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001567 ALOGV("%s: Camera %d: Discarding recording image buffers received after "
1568 "recording done",
1569 __FUNCTION__, mCameraId);
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07001570 mRecordingConsumer->releaseBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001571 return;
1572 }
Eino-Ville Talvala898a9a92012-07-20 11:05:20 -07001573
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001574 if (mRecordingHeap == 0) {
1575 const size_t bufferSize = 4 + sizeof(buffer_handle_t);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001576 ALOGV("%s: Camera %d: Creating recording heap with %d buffers of "
1577 "size %d bytes", __FUNCTION__, mCameraId,
James Dong983cf232012-08-01 16:39:55 -07001578 mRecordingHeapCount, bufferSize);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001579
James Dong983cf232012-08-01 16:39:55 -07001580 mRecordingHeap = new Camera2Heap(bufferSize, mRecordingHeapCount,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001581 "Camera2Client::RecordingHeap");
1582 if (mRecordingHeap->mHeap->getSize() == 0) {
1583 ALOGE("%s: Camera %d: Unable to allocate memory for recording",
1584 __FUNCTION__, mCameraId);
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07001585 mRecordingConsumer->releaseBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001586 return;
1587 }
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07001588 for (size_t i = 0; i < mRecordingBuffers.size(); i++) {
1589 if (mRecordingBuffers[i].mBuf !=
1590 BufferItemConsumer::INVALID_BUFFER_SLOT) {
1591 ALOGE("%s: Camera %d: Non-empty recording buffers list!",
1592 __FUNCTION__, mCameraId);
1593 }
1594 }
1595 mRecordingBuffers.clear();
1596 mRecordingBuffers.setCapacity(mRecordingHeapCount);
1597 mRecordingBuffers.insertAt(0, mRecordingHeapCount);
1598
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001599 mRecordingHeapHead = 0;
James Dong983cf232012-08-01 16:39:55 -07001600 mRecordingHeapFree = mRecordingHeapCount;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001601 }
1602
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001603 if ( mRecordingHeapFree == 0) {
1604 ALOGE("%s: Camera %d: No free recording buffers, dropping frame",
1605 __FUNCTION__, mCameraId);
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07001606 mRecordingConsumer->releaseBuffer(imgBuffer);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001607 return;
1608 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001609
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001610 heapIdx = mRecordingHeapHead;
James Dong983cf232012-08-01 16:39:55 -07001611 mRecordingHeapHead = (mRecordingHeapHead + 1) % mRecordingHeapCount;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001612 mRecordingHeapFree--;
1613
1614 ALOGV("%s: Camera %d: Timestamp %lld",
1615 __FUNCTION__, mCameraId, timestamp);
1616
1617 ssize_t offset;
1618 size_t size;
1619 sp<IMemoryHeap> heap =
1620 mRecordingHeap->mBuffers[heapIdx]->getMemory(&offset,
1621 &size);
1622
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001623 uint8_t *data = (uint8_t*)heap->getBase() + offset;
1624 uint32_t type = kMetadataBufferTypeGrallocSource;
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07001625 *((uint32_t*)data) = type;
1626 *((buffer_handle_t*)(data + 4)) = imgBuffer.mGraphicBuffer->handle;
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001627 ALOGV("%s: Camera %d: Sending out buffer_handle_t %p",
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07001628 __FUNCTION__, mCameraId, imgBuffer.mGraphicBuffer->handle);
1629 mRecordingBuffers.replaceAt(imgBuffer, heapIdx);
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001630 recordingHeap = mRecordingHeap;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001631 }
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001632
1633 // Call outside locked parameters to allow re-entrancy from notification
Eino-Ville Talvalaa16733e2012-08-27 23:41:56 -07001634 SharedCameraClient::Lock l(mSharedCameraClient);
1635 if (l.mCameraClient != 0) {
1636 l.mCameraClient->dataCallbackTimestamp(timestamp,
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001637 CAMERA_MSG_VIDEO_FRAME,
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001638 recordingHeap->mBuffers[heapIdx]);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001639 }
1640}
1641
Eino-Ville Talvala3cca1362012-06-07 10:07:18 -07001642/** Utility methods */
1643
Eino-Ville Talvalaf98cbbe2012-08-29 18:06:32 -07001644status_t Camera2Client::updateRequests(Parameters &params) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001645 status_t res;
1646
1647 res = updatePreviewRequest(params);
1648 if (res != OK) {
1649 ALOGE("%s: Camera %d: Unable to update preview request: %s (%d)",
1650 __FUNCTION__, mCameraId, strerror(-res), res);
1651 return res;
1652 }
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001653 res = updateRecordingRequest(params);
1654 if (res != OK) {
1655 ALOGE("%s: Camera %d: Unable to update recording request: %s (%d)",
1656 __FUNCTION__, mCameraId, strerror(-res), res);
1657 return res;
1658 }
1659
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001660 if (params.state == Parameters::PREVIEW) {
Eino-Ville Talvalaf98cbbe2012-08-29 18:06:32 -07001661 res = startPreviewL(params, true);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001662 if (res != OK) {
1663 ALOGE("%s: Camera %d: Error streaming new preview request: %s (%d)",
1664 __FUNCTION__, mCameraId, strerror(-res), res);
1665 return res;
1666 }
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -07001667 } else if (params.state == Parameters::RECORD ||
1668 params.state == Parameters::VIDEO_SNAPSHOT) {
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001669 res = mDevice->setStreamingRequest(mRecordingRequest);
1670 if (res != OK) {
1671 ALOGE("%s: Camera %d: Error streaming new record request: %s (%d)",
1672 __FUNCTION__, mCameraId, strerror(-res), res);
1673 return res;
1674 }
1675 }
1676 return res;
1677}
1678
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001679status_t Camera2Client::updatePreviewStream(const Parameters &params) {
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001680 ATRACE_CALL();
1681 status_t res;
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001682
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001683 if (mPreviewStreamId != NO_STREAM) {
1684 // Check if stream parameters have to change
1685 uint32_t currentWidth, currentHeight;
1686 res = mDevice->getStreamInfo(mPreviewStreamId,
1687 &currentWidth, &currentHeight, 0);
1688 if (res != OK) {
1689 ALOGE("%s: Camera %d: Error querying preview stream info: "
1690 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
1691 return res;
1692 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001693 if (currentWidth != (uint32_t)params.previewWidth ||
1694 currentHeight != (uint32_t)params.previewHeight) {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -07001695 ALOGV("%s: Camera %d: Preview size switch: %d x %d -> %d x %d",
1696 __FUNCTION__, mCameraId, currentWidth, currentHeight,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001697 params.previewWidth, params.previewHeight);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001698 res = mDevice->waitUntilDrained();
1699 if (res != OK) {
1700 ALOGE("%s: Camera %d: Error waiting for preview to drain: "
1701 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
1702 return res;
1703 }
1704 res = mDevice->deleteStream(mPreviewStreamId);
1705 if (res != OK) {
1706 ALOGE("%s: Camera %d: Unable to delete old output stream "
1707 "for preview: %s (%d)", __FUNCTION__, mCameraId,
1708 strerror(-res), res);
1709 return res;
1710 }
1711 mPreviewStreamId = NO_STREAM;
1712 }
1713 }
1714
1715 if (mPreviewStreamId == NO_STREAM) {
1716 res = mDevice->createStream(mPreviewWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001717 params.previewWidth, params.previewHeight,
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001718 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0,
1719 &mPreviewStreamId);
1720 if (res != OK) {
1721 ALOGE("%s: Camera %d: Unable to create preview stream: %s (%d)",
1722 __FUNCTION__, mCameraId, strerror(-res), res);
1723 return res;
1724 }
1725 }
1726
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001727 res = mDevice->setStreamTransform(mPreviewStreamId,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001728 params.previewTransform);
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001729 if (res != OK) {
1730 ALOGE("%s: Camera %d: Unable to set preview stream transform: "
1731 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
1732 return res;
1733 }
1734
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001735 return OK;
1736}
1737
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001738status_t Camera2Client::updatePreviewRequest(const Parameters &params) {
Eino-Ville Talvalaa1890972012-05-31 11:18:52 -07001739 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001740 status_t res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001741 if (mPreviewRequest.entryCount() == 0) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001742 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
1743 &mPreviewRequest);
1744 if (res != OK) {
1745 ALOGE("%s: Camera %d: Unable to create default preview request: "
1746 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
1747 return res;
1748 }
1749 }
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001750
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001751 res = params.updateRequest(&mPreviewRequest);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001752 if (res != OK) {
1753 ALOGE("%s: Camera %d: Unable to update common entries of preview "
1754 "request: %s (%d)", __FUNCTION__, mCameraId,
1755 strerror(-res), res);
1756 return res;
1757 }
1758
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001759 res = mPreviewRequest.update(ANDROID_REQUEST_ID,
1760 &kPreviewRequestId, 1);
Eino-Ville Talvalabe0573b2012-06-15 12:42:30 -07001761
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001762 return OK;
1763}
1764
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001765status_t Camera2Client::updateRecordingRequest(const Parameters &params) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001766 ATRACE_CALL();
1767 status_t res;
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -07001768 if (mRecordingRequest.entryCount() == 0) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001769 res = mDevice->createDefaultRequest(CAMERA2_TEMPLATE_VIDEO_RECORD,
1770 &mRecordingRequest);
1771 if (res != OK) {
1772 ALOGE("%s: Camera %d: Unable to create default recording request:"
1773 " %s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
1774 return res;
1775 }
1776 }
1777
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001778 res = params.updateRequest(&mRecordingRequest);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001779 if (res != OK) {
1780 ALOGE("%s: Camera %d: Unable to update common entries of recording "
1781 "request: %s (%d)", __FUNCTION__, mCameraId,
1782 strerror(-res), res);
1783 return res;
1784 }
1785
1786 return OK;
1787}
1788
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001789status_t Camera2Client::updateRecordingStream(const Parameters &params) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001790 status_t res;
1791
1792 if (mRecordingConsumer == 0) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001793 // Create CPU buffer queue endpoint. We need one more buffer here so that we can
1794 // always acquire and free a buffer when the heap is full; otherwise the consumer
1795 // will have buffers in flight we'll never clear out.
Eino-Ville Talvala30e65e72012-08-21 13:30:45 -07001796 mRecordingConsumer = new BufferItemConsumer(
1797 GRALLOC_USAGE_HW_VIDEO_ENCODER,
1798 mRecordingHeapCount + 1,
1799 true);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001800 mRecordingConsumer->setFrameAvailableListener(new RecordingWaiter(this));
1801 mRecordingConsumer->setName(String8("Camera2Client::RecordingConsumer"));
1802 mRecordingWindow = new SurfaceTextureClient(
1803 mRecordingConsumer->getProducerInterface());
1804 // Allocate memory later, since we don't know buffer size until receipt
1805 }
1806
1807 if (mRecordingStreamId != NO_STREAM) {
1808 // Check if stream parameters have to change
1809 uint32_t currentWidth, currentHeight;
1810 res = mDevice->getStreamInfo(mRecordingStreamId,
1811 &currentWidth, &currentHeight, 0);
1812 if (res != OK) {
1813 ALOGE("%s: Camera %d: Error querying recording output stream info: "
1814 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
1815 return res;
1816 }
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001817 if (currentWidth != (uint32_t)params.videoWidth ||
1818 currentHeight != (uint32_t)params.videoHeight) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001819 // TODO: Should wait to be sure previous recording has finished
1820 res = mDevice->deleteStream(mRecordingStreamId);
1821 if (res != OK) {
1822 ALOGE("%s: Camera %d: Unable to delete old output stream "
1823 "for recording: %s (%d)", __FUNCTION__, mCameraId,
1824 strerror(-res), res);
1825 return res;
1826 }
1827 mRecordingStreamId = NO_STREAM;
1828 }
1829 }
1830
1831 if (mRecordingStreamId == NO_STREAM) {
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001832 mRecordingFrameCount = 0;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001833 res = mDevice->createStream(mRecordingWindow,
Eino-Ville Talvala836b81f2012-07-27 11:35:21 -07001834 params.videoWidth, params.videoHeight,
Eino-Ville Talvala78822d72012-07-18 17:52:18 -07001835 CAMERA2_HAL_PIXEL_FORMAT_OPAQUE, 0, &mRecordingStreamId);
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001836 if (res != OK) {
1837 ALOGE("%s: Camera %d: Can't create output stream for recording: "
1838 "%s (%d)", __FUNCTION__, mCameraId, strerror(-res), res);
1839 return res;
1840 }
1841 }
1842
1843 return OK;
1844}
1845
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001846size_t Camera2Client::calculateBufferSize(int width, int height,
1847 int format, int stride) {
1848 switch (format) {
1849 case HAL_PIXEL_FORMAT_YCbCr_422_SP: // NV16
1850 return width * height * 2;
1851 case HAL_PIXEL_FORMAT_YCrCb_420_SP: // NV21
1852 return width * height * 3 / 2;
1853 case HAL_PIXEL_FORMAT_YCbCr_422_I: // YUY2
1854 return width * height * 2;
1855 case HAL_PIXEL_FORMAT_YV12: { // YV12
1856 size_t ySize = stride * height;
Eino-Ville Talvalaf17b6cf2012-08-25 17:12:18 -07001857 size_t uvStride = (stride / 2 + 0xF) & ~0xF;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001858 size_t uvSize = uvStride * height / 2;
1859 return ySize + uvSize * 2;
1860 }
1861 case HAL_PIXEL_FORMAT_RGB_565:
1862 return width * height * 2;
1863 case HAL_PIXEL_FORMAT_RGBA_8888:
1864 return width * height * 4;
1865 case HAL_PIXEL_FORMAT_RAW_SENSOR:
1866 return width * height * 2;
1867 default:
1868 ALOGE("%s: Unknown preview format: %x",
1869 __FUNCTION__, format);
1870 return 0;
1871 }
1872}
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -07001873
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001874} // namespace android