blob: 81c0496a765b285a192af23eac4668c7c212a923 [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 "Camera2Device"
18//#define LOG_NDEBUG 0
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -070019//#define LOG_NNDEBUG 0 // Per-frame verbose logging
20
21#ifdef LOG_NNDEBUG
22#define ALOGVV(...) ALOGV(__VA_ARGS__)
23#else
24#define ALOGVV(...) ((void)0)
25#endif
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070026
27#include <utils/Log.h>
28#include "Camera2Device.h"
29
30namespace android {
31
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070032Camera2Device::Camera2Device(int id):
33 mId(id),
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070034 mDevice(NULL)
35{
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -070036 ALOGV("%s: Created device for camera %d", __FUNCTION__, id);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070037}
38
39Camera2Device::~Camera2Device()
40{
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -070041 disconnect();
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070042}
43
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070044status_t Camera2Device::initialize(camera_module_t *module)
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070045{
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -070046 ALOGV("%s: Initializing device for camera %d", __FUNCTION__, mId);
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -070047 if (mDevice != NULL) {
48 ALOGE("%s: Already initialized!", __FUNCTION__);
49 return INVALID_OPERATION;
50 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -070051
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070052 status_t res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070053 char name[10];
54 snprintf(name, sizeof(name), "%d", mId);
55
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -070056 camera2_device_t *device;
57
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070058 res = module->common.methods->open(&module->common, name,
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -070059 reinterpret_cast<hw_device_t**>(&device));
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070060
61 if (res != OK) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070062 ALOGE("%s: Could not open camera %d: %s (%d)", __FUNCTION__,
63 mId, strerror(-res), res);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070064 return res;
65 }
66
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -070067 if (device->common.version != CAMERA_DEVICE_API_VERSION_2_0) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070068 ALOGE("%s: Could not open camera %d: "
69 "Camera device is not version %x, reports %x instead",
70 __FUNCTION__, mId, CAMERA_DEVICE_API_VERSION_2_0,
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -070071 device->common.version);
72 device->common.close(&device->common);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070073 return BAD_VALUE;
74 }
75
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070076 camera_info info;
77 res = module->get_camera_info(mId, &info);
78 if (res != OK ) return res;
79
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -070080 if (info.device_version != device->common.version) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070081 ALOGE("%s: HAL reporting mismatched camera_info version (%x)"
82 " and device version (%x).", __FUNCTION__,
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -070083 device->common.version, info.device_version);
84 device->common.close(&device->common);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070085 return BAD_VALUE;
86 }
87
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -070088 res = mRequestQueue.setConsumerDevice(device);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -070089 if (res != OK) {
90 ALOGE("%s: Camera %d: Unable to connect request queue to device: %s (%d)",
91 __FUNCTION__, mId, strerror(-res), res);
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -070092 device->common.close(&device->common);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -070093 return res;
94 }
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -070095 res = mFrameQueue.setProducerDevice(device);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -070096 if (res != OK) {
97 ALOGE("%s: Camera %d: Unable to connect frame queue to device: %s (%d)",
98 __FUNCTION__, mId, strerror(-res), res);
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -070099 device->common.close(&device->common);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700100 return res;
101 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700102
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -0700103 res = device->ops->get_metadata_vendor_tag_ops(device, &mVendorTagOps);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700104 if (res != OK ) {
105 ALOGE("%s: Camera %d: Unable to retrieve tag ops from device: %s (%d)",
106 __FUNCTION__, mId, strerror(-res), res);
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -0700107 device->common.close(&device->common);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700108 return res;
109 }
Shuzhen Wang092fe442012-08-31 10:24:22 -0700110 res = set_camera_metadata_vendor_tag_ops(mVendorTagOps);
111 if (res != OK) {
112 ALOGE("%s: Camera %d: Unable to set tag ops: %s (%d)",
113 __FUNCTION__, mId, strerror(-res), res);
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -0700114 device->common.close(&device->common);
Shuzhen Wang092fe442012-08-31 10:24:22 -0700115 return res;
116 }
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -0700117 res = device->ops->set_notify_callback(device, notificationCallback,
118 NULL);
119 if (res != OK) {
120 ALOGE("%s: Camera %d: Unable to initialize notification callback!",
121 __FUNCTION__, mId);
122 device->common.close(&device->common);
123 return res;
124 }
125
126 mDeviceInfo = info.static_camera_characteristics;
127 mDevice = device;
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700128
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700129 return OK;
130}
131
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -0700132status_t Camera2Device::disconnect() {
133 status_t res = OK;
134 if (mDevice) {
135 ALOGV("%s: Closing device for camera %d", __FUNCTION__, mId);
136
137 int inProgressCount = mDevice->ops->get_in_progress_count(mDevice);
138 if (inProgressCount > 0) {
139 ALOGW("%s: Closing camera device %d with %d requests in flight!",
140 __FUNCTION__, mId, inProgressCount);
141 }
142 mStreams.clear();
143 res = mDevice->common.close(&mDevice->common);
144 if (res != OK) {
145 ALOGE("%s: Could not close camera %d: %s (%d)",
146 __FUNCTION__,
147 mId, strerror(-res), res);
148 }
149 mDevice = NULL;
150 ALOGV("%s: Shutdown complete", __FUNCTION__);
151 }
152 return res;
153}
154
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700155status_t Camera2Device::dump(int fd, const Vector<String16>& args) {
156
157 String8 result;
Eino-Ville Talvala97197152012-08-06 14:25:19 -0700158 int detailLevel = 0;
159 int n = args.size();
160 String16 detailOption("-d");
161 for (int i = 0; i + 1 < n; i++) {
162 if (args[i] == detailOption) {
163 String8 levelStr(args[i+1]);
164 detailLevel = atoi(levelStr.string());
165 }
166 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700167
Eino-Ville Talvala603b12e2012-08-08 09:25:58 -0700168 result.appendFormat(" Camera2Device[%d] dump (detail level %d):\n",
169 mId, detailLevel);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700170
Eino-Ville Talvala97197152012-08-06 14:25:19 -0700171 if (detailLevel > 0) {
172 result = " Request queue contents:\n";
173 write(fd, result.string(), result.size());
174 mRequestQueue.dump(fd, args);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700175
Eino-Ville Talvala97197152012-08-06 14:25:19 -0700176 result = " Frame queue contents:\n";
177 write(fd, result.string(), result.size());
178 mFrameQueue.dump(fd, args);
179 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700180
181 result = " Active streams:\n";
182 write(fd, result.string(), result.size());
183 for (StreamList::iterator s = mStreams.begin(); s != mStreams.end(); s++) {
184 (*s)->dump(fd, args);
185 }
186
187 result = " HAL device dump:\n";
188 write(fd, result.string(), result.size());
189
190 status_t res;
191 res = mDevice->ops->dump(mDevice, fd);
192
193 return res;
194}
195
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700196const camera2::CameraMetadata& Camera2Device::info() const {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700197 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700198
199 return mDeviceInfo;
200}
201
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700202status_t Camera2Device::capture(CameraMetadata &request) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700203 ALOGV("%s: E", __FUNCTION__);
204
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700205 mRequestQueue.enqueue(request.release());
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700206 return OK;
207}
208
209
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700210status_t Camera2Device::setStreamingRequest(const CameraMetadata &request) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700211 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700212 CameraMetadata streamRequest(request);
213 return mRequestQueue.setStreamSlot(streamRequest.release());
214}
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700215
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700216status_t Camera2Device::clearStreamingRequest() {
217 return mRequestQueue.setStreamSlot(NULL);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700218}
219
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700220status_t Camera2Device::createStream(sp<ANativeWindow> consumer,
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700221 uint32_t width, uint32_t height, int format, size_t size, int *id) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700222 status_t res;
223 ALOGV("%s: E", __FUNCTION__);
224
225 sp<StreamAdapter> stream = new StreamAdapter(mDevice);
226
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700227 res = stream->connectToDevice(consumer, width, height, format, size);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700228 if (res != OK) {
229 ALOGE("%s: Camera %d: Unable to create stream (%d x %d, format %x):"
230 "%s (%d)",
231 __FUNCTION__, mId, width, height, format, strerror(-res), res);
232 return res;
233 }
234
235 *id = stream->getId();
236
237 mStreams.push_back(stream);
238 return OK;
239}
240
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700241status_t Camera2Device::createReprocessStreamFromStream(int outputId, int *id) {
242 status_t res;
243 ALOGV("%s: E", __FUNCTION__);
244
245 bool found = false;
246 StreamList::iterator streamI;
247 for (streamI = mStreams.begin();
248 streamI != mStreams.end(); streamI++) {
249 if ((*streamI)->getId() == outputId) {
250 found = true;
251 break;
252 }
253 }
254 if (!found) {
255 ALOGE("%s: Camera %d: Output stream %d doesn't exist; can't create "
256 "reprocess stream from it!", __FUNCTION__, mId, outputId);
257 return BAD_VALUE;
258 }
259
260 sp<ReprocessStreamAdapter> stream = new ReprocessStreamAdapter(mDevice);
261
262 res = stream->connectToDevice((*streamI));
263 if (res != OK) {
264 ALOGE("%s: Camera %d: Unable to create reprocessing stream from "\
265 "stream %d: %s (%d)", __FUNCTION__, mId, outputId,
266 strerror(-res), res);
267 return res;
268 }
269
270 *id = stream->getId();
271
272 mReprocessStreams.push_back(stream);
273 return OK;
274}
275
276
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700277status_t Camera2Device::getStreamInfo(int id,
278 uint32_t *width, uint32_t *height, uint32_t *format) {
279 ALOGV("%s: E", __FUNCTION__);
280 bool found = false;
281 StreamList::iterator streamI;
282 for (streamI = mStreams.begin();
283 streamI != mStreams.end(); streamI++) {
284 if ((*streamI)->getId() == id) {
285 found = true;
286 break;
287 }
288 }
289 if (!found) {
290 ALOGE("%s: Camera %d: Stream %d does not exist",
291 __FUNCTION__, mId, id);
292 return BAD_VALUE;
293 }
294
295 if (width) *width = (*streamI)->getWidth();
296 if (height) *height = (*streamI)->getHeight();
297 if (format) *format = (*streamI)->getFormat();
298
299 return OK;
300}
301
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -0700302status_t Camera2Device::setStreamTransform(int id,
303 int transform) {
304 ALOGV("%s: E", __FUNCTION__);
305 bool found = false;
306 StreamList::iterator streamI;
307 for (streamI = mStreams.begin();
308 streamI != mStreams.end(); streamI++) {
309 if ((*streamI)->getId() == id) {
310 found = true;
311 break;
312 }
313 }
314 if (!found) {
315 ALOGE("%s: Camera %d: Stream %d does not exist",
316 __FUNCTION__, mId, id);
317 return BAD_VALUE;
318 }
319
320 return (*streamI)->setTransform(transform);
321}
322
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700323status_t Camera2Device::deleteStream(int id) {
324 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700325 bool found = false;
326 for (StreamList::iterator streamI = mStreams.begin();
327 streamI != mStreams.end(); streamI++) {
328 if ((*streamI)->getId() == id) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700329 status_t res = (*streamI)->release();
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700330 if (res != OK) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700331 ALOGE("%s: Unable to release stream %d from HAL device: "
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700332 "%s (%d)", __FUNCTION__, id, strerror(-res), res);
333 return res;
334 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700335 mStreams.erase(streamI);
336 found = true;
337 break;
338 }
339 }
340 if (!found) {
341 ALOGE("%s: Camera %d: Unable to find stream %d to delete",
342 __FUNCTION__, mId, id);
343 return BAD_VALUE;
344 }
345 return OK;
346}
347
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700348status_t Camera2Device::deleteReprocessStream(int id) {
349 ALOGV("%s: E", __FUNCTION__);
350 bool found = false;
351 for (ReprocessStreamList::iterator streamI = mReprocessStreams.begin();
352 streamI != mReprocessStreams.end(); streamI++) {
353 if ((*streamI)->getId() == id) {
354 status_t res = (*streamI)->release();
355 if (res != OK) {
356 ALOGE("%s: Unable to release reprocess stream %d from "
357 "HAL device: %s (%d)", __FUNCTION__, id,
358 strerror(-res), res);
359 return res;
360 }
361 mReprocessStreams.erase(streamI);
362 found = true;
363 break;
364 }
365 }
366 if (!found) {
367 ALOGE("%s: Camera %d: Unable to find stream %d to delete",
368 __FUNCTION__, mId, id);
369 return BAD_VALUE;
370 }
371 return OK;
372}
373
374
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700375status_t Camera2Device::createDefaultRequest(int templateId,
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700376 CameraMetadata *request) {
377 status_t err;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700378 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700379 camera_metadata_t *rawRequest;
380 err = mDevice->ops->construct_default_request(
381 mDevice, templateId, &rawRequest);
382 request->acquire(rawRequest);
383 return err;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700384}
385
386status_t Camera2Device::waitUntilDrained() {
387 static const uint32_t kSleepTime = 50000; // 50 ms
388 static const uint32_t kMaxSleepTime = 10000000; // 10 s
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -0700389 ALOGV("%s: Camera %d: Starting wait", __FUNCTION__, mId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700390 if (mRequestQueue.getBufferCount() ==
391 CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS) return INVALID_OPERATION;
392
393 // TODO: Set up notifications from HAL, instead of sleeping here
394 uint32_t totalTime = 0;
395 while (mDevice->ops->get_in_progress_count(mDevice) > 0) {
396 usleep(kSleepTime);
397 totalTime += kSleepTime;
398 if (totalTime > kMaxSleepTime) {
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -0700399 ALOGE("%s: Waited %d us, %d requests still in flight", __FUNCTION__,
400 mDevice->ops->get_in_progress_count(mDevice), totalTime);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700401 return TIMED_OUT;
402 }
403 }
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -0700404 ALOGV("%s: Camera %d: HAL is idle", __FUNCTION__, mId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700405 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700406}
407
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700408status_t Camera2Device::setNotifyCallback(NotificationListener *listener) {
409 status_t res;
410 res = mDevice->ops->set_notify_callback(mDevice, notificationCallback,
411 reinterpret_cast<void*>(listener) );
412 if (res != OK) {
413 ALOGE("%s: Unable to set notification callback!", __FUNCTION__);
414 }
415 return res;
416}
417
418void Camera2Device::notificationCallback(int32_t msg_type,
419 int32_t ext1,
420 int32_t ext2,
421 int32_t ext3,
422 void *user) {
423 NotificationListener *listener = reinterpret_cast<NotificationListener*>(user);
424 ALOGV("%s: Notification %d, arguments %d, %d, %d", __FUNCTION__, msg_type,
425 ext1, ext2, ext3);
426 if (listener != NULL) {
427 switch (msg_type) {
428 case CAMERA2_MSG_ERROR:
429 listener->notifyError(ext1, ext2, ext3);
430 break;
431 case CAMERA2_MSG_SHUTTER: {
432 nsecs_t timestamp = (nsecs_t)ext2 | ((nsecs_t)(ext3) << 32 );
433 listener->notifyShutter(ext1, timestamp);
434 break;
435 }
436 case CAMERA2_MSG_AUTOFOCUS:
437 listener->notifyAutoFocus(ext1, ext2);
438 break;
439 case CAMERA2_MSG_AUTOEXPOSURE:
440 listener->notifyAutoExposure(ext1, ext2);
441 break;
442 case CAMERA2_MSG_AUTOWB:
443 listener->notifyAutoWhitebalance(ext1, ext2);
444 break;
445 default:
446 ALOGE("%s: Unknown notification %d (arguments %d, %d, %d)!",
447 __FUNCTION__, msg_type, ext1, ext2, ext3);
448 }
449 }
450}
451
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -0700452status_t Camera2Device::waitForNextFrame(nsecs_t timeout) {
453 return mFrameQueue.waitForBuffer(timeout);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700454}
455
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700456status_t Camera2Device::getNextFrame(CameraMetadata *frame) {
457 status_t res;
458 camera_metadata_t *rawFrame;
459 res = mFrameQueue.dequeue(&rawFrame);
460 if (rawFrame == NULL) {
461 return NOT_ENOUGH_DATA;
462 } else if (res == OK) {
463 frame->acquire(rawFrame);
464 }
465 return res;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700466}
467
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700468status_t Camera2Device::triggerAutofocus(uint32_t id) {
469 status_t res;
470 ALOGV("%s: Triggering autofocus, id %d", __FUNCTION__, id);
471 res = mDevice->ops->trigger_action(mDevice,
472 CAMERA2_TRIGGER_AUTOFOCUS, id, 0);
473 if (res != OK) {
474 ALOGE("%s: Error triggering autofocus (id %d)",
475 __FUNCTION__, id);
476 }
477 return res;
478}
479
480status_t Camera2Device::triggerCancelAutofocus(uint32_t id) {
481 status_t res;
482 ALOGV("%s: Canceling autofocus, id %d", __FUNCTION__, id);
483 res = mDevice->ops->trigger_action(mDevice,
484 CAMERA2_TRIGGER_CANCEL_AUTOFOCUS, id, 0);
485 if (res != OK) {
486 ALOGE("%s: Error canceling autofocus (id %d)",
487 __FUNCTION__, id);
488 }
489 return res;
490}
491
492status_t Camera2Device::triggerPrecaptureMetering(uint32_t id) {
493 status_t res;
494 ALOGV("%s: Triggering precapture metering, id %d", __FUNCTION__, id);
495 res = mDevice->ops->trigger_action(mDevice,
496 CAMERA2_TRIGGER_PRECAPTURE_METERING, id, 0);
497 if (res != OK) {
498 ALOGE("%s: Error triggering precapture metering (id %d)",
499 __FUNCTION__, id);
500 }
501 return res;
502}
503
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700504status_t Camera2Device::pushReprocessBuffer(int reprocessStreamId,
505 buffer_handle_t *buffer, wp<BufferReleasedListener> listener) {
506 ALOGV("%s: E", __FUNCTION__);
507 bool found = false;
508 status_t res = OK;
509 for (ReprocessStreamList::iterator streamI = mReprocessStreams.begin();
510 streamI != mReprocessStreams.end(); streamI++) {
511 if ((*streamI)->getId() == reprocessStreamId) {
512 res = (*streamI)->pushIntoStream(buffer, listener);
513 if (res != OK) {
514 ALOGE("%s: Unable to push buffer to reprocess stream %d: %s (%d)",
515 __FUNCTION__, reprocessStreamId, strerror(-res), res);
516 return res;
517 }
518 found = true;
519 break;
520 }
521 }
522 if (!found) {
523 ALOGE("%s: Camera %d: Unable to find reprocess stream %d",
524 __FUNCTION__, mId, reprocessStreamId);
525 res = BAD_VALUE;
526 }
527 return res;
528}
529
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700530/**
531 * Camera2Device::NotificationListener
532 */
533
534Camera2Device::NotificationListener::~NotificationListener() {
535}
536
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700537/**
538 * Camera2Device::MetadataQueue
539 */
540
541Camera2Device::MetadataQueue::MetadataQueue():
542 mDevice(NULL),
543 mFrameCount(0),
544 mCount(0),
545 mStreamSlotCount(0),
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -0700546 mSignalConsumer(true)
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700547{
548 camera2_request_queue_src_ops::dequeue_request = consumer_dequeue;
549 camera2_request_queue_src_ops::request_count = consumer_buffer_count;
550 camera2_request_queue_src_ops::free_request = consumer_free;
551
552 camera2_frame_queue_dst_ops::dequeue_frame = producer_dequeue;
553 camera2_frame_queue_dst_ops::cancel_frame = producer_cancel;
554 camera2_frame_queue_dst_ops::enqueue_frame = producer_enqueue;
555}
556
557Camera2Device::MetadataQueue::~MetadataQueue() {
558 Mutex::Autolock l(mMutex);
559 freeBuffers(mEntries.begin(), mEntries.end());
560 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
561}
562
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700563// Connect to camera2 HAL as consumer (input requests/reprocessing)
564status_t Camera2Device::MetadataQueue::setConsumerDevice(camera2_device_t *d) {
565 status_t res;
566 res = d->ops->set_request_queue_src_ops(d,
567 this);
568 if (res != OK) return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700569 mDevice = d;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700570 return OK;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700571}
572
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700573status_t Camera2Device::MetadataQueue::setProducerDevice(camera2_device_t *d) {
574 status_t res;
575 res = d->ops->set_frame_queue_dst_ops(d,
576 this);
577 return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700578}
579
580// Real interfaces
581status_t Camera2Device::MetadataQueue::enqueue(camera_metadata_t *buf) {
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700582 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700583 Mutex::Autolock l(mMutex);
584
585 mCount++;
586 mEntries.push_back(buf);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700587
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700588 return signalConsumerLocked();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700589}
590
591int Camera2Device::MetadataQueue::getBufferCount() {
592 Mutex::Autolock l(mMutex);
593 if (mStreamSlotCount > 0) {
594 return CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS;
595 }
596 return mCount;
597}
598
599status_t Camera2Device::MetadataQueue::dequeue(camera_metadata_t **buf,
600 bool incrementCount)
601{
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700602 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700603 status_t res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700604 Mutex::Autolock l(mMutex);
605
606 if (mCount == 0) {
607 if (mStreamSlotCount == 0) {
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700608 ALOGVV("%s: Empty", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700609 *buf = NULL;
610 mSignalConsumer = true;
611 return OK;
612 }
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700613 ALOGVV("%s: Streaming %d frames to queue", __FUNCTION__,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700614 mStreamSlotCount);
615
616 for (List<camera_metadata_t*>::iterator slotEntry = mStreamSlot.begin();
617 slotEntry != mStreamSlot.end();
618 slotEntry++ ) {
619 size_t entries = get_camera_metadata_entry_count(*slotEntry);
620 size_t dataBytes = get_camera_metadata_data_count(*slotEntry);
621
622 camera_metadata_t *copy =
623 allocate_camera_metadata(entries, dataBytes);
624 append_camera_metadata(copy, *slotEntry);
625 mEntries.push_back(copy);
626 }
627 mCount = mStreamSlotCount;
628 }
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700629 ALOGVV("MetadataQueue: deque (%d buffers)", mCount);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700630 camera_metadata_t *b = *(mEntries.begin());
631 mEntries.erase(mEntries.begin());
632
633 if (incrementCount) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700634 camera_metadata_entry_t frameCount;
635 res = find_camera_metadata_entry(b,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700636 ANDROID_REQUEST_FRAME_COUNT,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700637 &frameCount);
638 if (res != OK) {
639 ALOGE("%s: Unable to add frame count: %s (%d)",
640 __FUNCTION__, strerror(-res), res);
641 } else {
642 *frameCount.data.i32 = mFrameCount;
643 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700644 mFrameCount++;
645 }
646
647 *buf = b;
648 mCount--;
649
650 return OK;
651}
652
653status_t Camera2Device::MetadataQueue::waitForBuffer(nsecs_t timeout)
654{
655 Mutex::Autolock l(mMutex);
656 status_t res;
657 while (mCount == 0) {
658 res = notEmpty.waitRelative(mMutex,timeout);
659 if (res != OK) return res;
660 }
661 return OK;
662}
663
664status_t Camera2Device::MetadataQueue::setStreamSlot(camera_metadata_t *buf)
665{
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700666 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700667 Mutex::Autolock l(mMutex);
668 if (buf == NULL) {
669 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
670 mStreamSlotCount = 0;
671 return OK;
672 }
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700673 camera_metadata_t *buf2 = clone_camera_metadata(buf);
674 if (!buf2) {
675 ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__);
676 return NO_MEMORY;
677 }
678
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700679 if (mStreamSlotCount > 1) {
680 List<camera_metadata_t*>::iterator deleter = ++mStreamSlot.begin();
681 freeBuffers(++mStreamSlot.begin(), mStreamSlot.end());
682 mStreamSlotCount = 1;
683 }
684 if (mStreamSlotCount == 1) {
685 free_camera_metadata( *(mStreamSlot.begin()) );
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700686 *(mStreamSlot.begin()) = buf2;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700687 } else {
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700688 mStreamSlot.push_front(buf2);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700689 mStreamSlotCount = 1;
690 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700691 return signalConsumerLocked();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700692}
693
694status_t Camera2Device::MetadataQueue::setStreamSlot(
695 const List<camera_metadata_t*> &bufs)
696{
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700697 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700698 Mutex::Autolock l(mMutex);
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700699 status_t res;
700
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700701 if (mStreamSlotCount > 0) {
702 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
703 }
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700704 mStreamSlotCount = 0;
705 for (List<camera_metadata_t*>::const_iterator r = bufs.begin();
706 r != bufs.end(); r++) {
707 camera_metadata_t *r2 = clone_camera_metadata(*r);
708 if (!r2) {
709 ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__);
710 return NO_MEMORY;
711 }
712 mStreamSlot.push_back(r2);
713 mStreamSlotCount++;
714 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700715 return signalConsumerLocked();
716}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700717
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700718status_t Camera2Device::MetadataQueue::dump(int fd,
719 const Vector<String16>& args) {
720 String8 result;
721 status_t notLocked;
722 notLocked = mMutex.tryLock();
723 if (notLocked) {
724 result.append(" (Unable to lock queue mutex)\n");
725 }
726 result.appendFormat(" Current frame number: %d\n", mFrameCount);
727 if (mStreamSlotCount == 0) {
728 result.append(" Stream slot: Empty\n");
729 write(fd, result.string(), result.size());
730 } else {
731 result.appendFormat(" Stream slot: %d entries\n",
732 mStreamSlot.size());
733 int i = 0;
734 for (List<camera_metadata_t*>::iterator r = mStreamSlot.begin();
735 r != mStreamSlot.end(); r++) {
736 result = String8::format(" Stream slot buffer %d:\n", i);
737 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700738 dump_indented_camera_metadata(*r, fd, 2, 10);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700739 i++;
740 }
741 }
742 if (mEntries.size() == 0) {
743 result = " Main queue is empty\n";
744 write(fd, result.string(), result.size());
745 } else {
746 result = String8::format(" Main queue has %d entries:\n",
747 mEntries.size());
748 int i = 0;
749 for (List<camera_metadata_t*>::iterator r = mEntries.begin();
750 r != mEntries.end(); r++) {
751 result = String8::format(" Queue entry %d:\n", i);
752 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700753 dump_indented_camera_metadata(*r, fd, 2, 10);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700754 i++;
755 }
756 }
757
758 if (notLocked == 0) {
759 mMutex.unlock();
760 }
761
762 return OK;
763}
764
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700765status_t Camera2Device::MetadataQueue::signalConsumerLocked() {
766 status_t res = OK;
767 notEmpty.signal();
768 if (mSignalConsumer && mDevice != NULL) {
769 mSignalConsumer = false;
770
771 mMutex.unlock();
772 ALOGV("%s: Signaling consumer", __FUNCTION__);
773 res = mDevice->ops->notify_request_queue_not_empty(mDevice);
774 mMutex.lock();
775 }
776 return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700777}
778
779status_t Camera2Device::MetadataQueue::freeBuffers(
780 List<camera_metadata_t*>::iterator start,
781 List<camera_metadata_t*>::iterator end)
782{
783 while (start != end) {
784 free_camera_metadata(*start);
785 start = mStreamSlot.erase(start);
786 }
787 return OK;
788}
789
790Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
791 const camera2_request_queue_src_ops_t *q)
792{
793 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
794 return const_cast<MetadataQueue*>(cmq);
795}
796
797Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
798 const camera2_frame_queue_dst_ops_t *q)
799{
800 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
801 return const_cast<MetadataQueue*>(cmq);
802}
803
804int Camera2Device::MetadataQueue::consumer_buffer_count(
805 const camera2_request_queue_src_ops_t *q)
806{
807 MetadataQueue *queue = getInstance(q);
808 return queue->getBufferCount();
809}
810
811int Camera2Device::MetadataQueue::consumer_dequeue(
812 const camera2_request_queue_src_ops_t *q,
813 camera_metadata_t **buffer)
814{
815 MetadataQueue *queue = getInstance(q);
816 return queue->dequeue(buffer, true);
817}
818
819int Camera2Device::MetadataQueue::consumer_free(
820 const camera2_request_queue_src_ops_t *q,
821 camera_metadata_t *old_buffer)
822{
823 MetadataQueue *queue = getInstance(q);
824 free_camera_metadata(old_buffer);
825 return OK;
826}
827
828int Camera2Device::MetadataQueue::producer_dequeue(
829 const camera2_frame_queue_dst_ops_t *q,
830 size_t entries, size_t bytes,
831 camera_metadata_t **buffer)
832{
833 camera_metadata_t *new_buffer =
834 allocate_camera_metadata(entries, bytes);
835 if (new_buffer == NULL) return NO_MEMORY;
836 *buffer = new_buffer;
837 return OK;
838}
839
840int Camera2Device::MetadataQueue::producer_cancel(
841 const camera2_frame_queue_dst_ops_t *q,
842 camera_metadata_t *old_buffer)
843{
844 free_camera_metadata(old_buffer);
845 return OK;
846}
847
848int Camera2Device::MetadataQueue::producer_enqueue(
849 const camera2_frame_queue_dst_ops_t *q,
850 camera_metadata_t *filled_buffer)
851{
852 MetadataQueue *queue = getInstance(q);
853 return queue->enqueue(filled_buffer);
854}
855
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700856/**
857 * Camera2Device::StreamAdapter
858 */
859
860#ifndef container_of
861#define container_of(ptr, type, member) \
862 (type *)((char*)(ptr) - offsetof(type, member))
863#endif
864
865Camera2Device::StreamAdapter::StreamAdapter(camera2_device_t *d):
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700866 mState(RELEASED),
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700867 mDevice(d),
868 mId(-1),
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700869 mWidth(0), mHeight(0), mFormat(0), mSize(0), mUsage(0),
870 mMaxProducerBuffers(0), mMaxConsumerBuffers(0),
871 mTotalBuffers(0),
872 mFormatRequested(0),
873 mActiveBuffers(0),
874 mFrameCount(0),
875 mLastTimestamp(0)
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700876{
877 camera2_stream_ops::dequeue_buffer = dequeue_buffer;
878 camera2_stream_ops::enqueue_buffer = enqueue_buffer;
879 camera2_stream_ops::cancel_buffer = cancel_buffer;
880 camera2_stream_ops::set_crop = set_crop;
881}
882
883Camera2Device::StreamAdapter::~StreamAdapter() {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700884 if (mState != RELEASED) {
885 release();
886 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700887}
888
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700889status_t Camera2Device::StreamAdapter::connectToDevice(
890 sp<ANativeWindow> consumer,
891 uint32_t width, uint32_t height, int format, size_t size) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700892 status_t res;
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700893 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700894
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700895 if (mState != RELEASED) return INVALID_OPERATION;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700896 if (consumer == NULL) {
897 ALOGE("%s: Null consumer passed to stream adapter", __FUNCTION__);
898 return BAD_VALUE;
899 }
900
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700901 ALOGV("%s: New stream parameters %d x %d, format 0x%x, size %d",
902 __FUNCTION__, width, height, format, size);
903
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700904 mConsumerInterface = consumer;
905 mWidth = width;
906 mHeight = height;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700907 mSize = (format == HAL_PIXEL_FORMAT_BLOB) ? size : 0;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700908 mFormatRequested = format;
909
910 // Allocate device-side stream interface
911
912 uint32_t id;
913 uint32_t formatActual;
914 uint32_t usage;
915 uint32_t maxBuffers = 2;
916 res = mDevice->ops->allocate_stream(mDevice,
917 mWidth, mHeight, mFormatRequested, getStreamOps(),
918 &id, &formatActual, &usage, &maxBuffers);
919 if (res != OK) {
920 ALOGE("%s: Device stream allocation failed: %s (%d)",
921 __FUNCTION__, strerror(-res), res);
922 return res;
923 }
924
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700925 ALOGV("%s: Allocated stream id %d, actual format 0x%x, "
926 "usage 0x%x, producer wants %d buffers", __FUNCTION__,
927 id, formatActual, usage, maxBuffers);
928
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700929 mId = id;
930 mFormat = formatActual;
931 mUsage = usage;
932 mMaxProducerBuffers = maxBuffers;
933
934 mState = ALLOCATED;
935
936 // Configure consumer-side ANativeWindow interface
937 res = native_window_api_connect(mConsumerInterface.get(),
938 NATIVE_WINDOW_API_CAMERA);
939 if (res != OK) {
940 ALOGE("%s: Unable to connect to native window for stream %d",
941 __FUNCTION__, mId);
942
943 return res;
944 }
945
946 mState = CONNECTED;
947
948 res = native_window_set_usage(mConsumerInterface.get(), mUsage);
949 if (res != OK) {
950 ALOGE("%s: Unable to configure usage %08x for stream %d",
951 __FUNCTION__, mUsage, mId);
952 return res;
953 }
954
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -0700955 res = native_window_set_scaling_mode(mConsumerInterface.get(),
956 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
957 if (res != OK) {
958 ALOGE("%s: Unable to configure stream scaling: %s (%d)",
959 __FUNCTION__, strerror(-res), res);
960 return res;
961 }
962
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -0700963 res = setTransform(0);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -0700964 if (res != OK) {
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -0700965 return res;
966 }
967
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700968 if (mFormat == HAL_PIXEL_FORMAT_BLOB) {
969 res = native_window_set_buffers_geometry(mConsumerInterface.get(),
970 mSize, 1, mFormat);
971 if (res != OK) {
972 ALOGE("%s: Unable to configure compressed stream buffer geometry"
973 " %d x %d, size %d for stream %d",
974 __FUNCTION__, mWidth, mHeight, mSize, mId);
975 return res;
976 }
977 } else {
978 res = native_window_set_buffers_geometry(mConsumerInterface.get(),
979 mWidth, mHeight, mFormat);
980 if (res != OK) {
981 ALOGE("%s: Unable to configure stream buffer geometry"
982 " %d x %d, format 0x%x for stream %d",
983 __FUNCTION__, mWidth, mHeight, mFormat, mId);
984 return res;
985 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700986 }
987
988 int maxConsumerBuffers;
989 res = mConsumerInterface->query(mConsumerInterface.get(),
990 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &maxConsumerBuffers);
991 if (res != OK) {
992 ALOGE("%s: Unable to query consumer undequeued"
993 " buffer count for stream %d", __FUNCTION__, mId);
994 return res;
995 }
996 mMaxConsumerBuffers = maxConsumerBuffers;
997
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700998 ALOGV("%s: Consumer wants %d buffers", __FUNCTION__,
999 mMaxConsumerBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001000
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001001 mTotalBuffers = mMaxConsumerBuffers + mMaxProducerBuffers;
1002 mActiveBuffers = 0;
1003 mFrameCount = 0;
1004 mLastTimestamp = 0;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001005
1006 res = native_window_set_buffer_count(mConsumerInterface.get(),
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001007 mTotalBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001008 if (res != OK) {
1009 ALOGE("%s: Unable to set buffer count for stream %d",
1010 __FUNCTION__, mId);
1011 return res;
1012 }
1013
1014 // Register allocated buffers with HAL device
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001015 buffer_handle_t *buffers = new buffer_handle_t[mTotalBuffers];
1016 ANativeWindowBuffer **anwBuffers = new ANativeWindowBuffer*[mTotalBuffers];
1017 uint32_t bufferIdx = 0;
1018 for (; bufferIdx < mTotalBuffers; bufferIdx++) {
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001019 res = native_window_dequeue_buffer_and_wait(mConsumerInterface.get(),
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001020 &anwBuffers[bufferIdx]);
1021 if (res != OK) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001022 ALOGE("%s: Unable to dequeue buffer %d for initial registration for "
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001023 "stream %d", __FUNCTION__, bufferIdx, mId);
1024 goto cleanUpBuffers;
1025 }
1026
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001027 buffers[bufferIdx] = anwBuffers[bufferIdx]->handle;
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -07001028 ALOGV("%s: Buffer %p allocated", __FUNCTION__, (void*)buffers[bufferIdx]);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001029 }
1030
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001031 ALOGV("%s: Registering %d buffers with camera HAL", __FUNCTION__, mTotalBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001032 res = mDevice->ops->register_stream_buffers(mDevice,
1033 mId,
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001034 mTotalBuffers,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001035 buffers);
1036 if (res != OK) {
1037 ALOGE("%s: Unable to register buffers with HAL device for stream %d",
1038 __FUNCTION__, mId);
1039 } else {
1040 mState = ACTIVE;
1041 }
1042
1043cleanUpBuffers:
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001044 ALOGV("%s: Cleaning up %d buffers", __FUNCTION__, bufferIdx);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001045 for (uint32_t i = 0; i < bufferIdx; i++) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001046 res = mConsumerInterface->cancelBuffer(mConsumerInterface.get(),
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001047 anwBuffers[i], -1);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001048 if (res != OK) {
1049 ALOGE("%s: Unable to cancel buffer %d after registration",
1050 __FUNCTION__, i);
1051 }
1052 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001053 delete[] anwBuffers;
1054 delete[] buffers;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001055
1056 return res;
1057}
1058
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001059status_t Camera2Device::StreamAdapter::release() {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001060 status_t res;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001061 ALOGV("%s: Releasing stream %d", __FUNCTION__, mId);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001062 if (mState >= ALLOCATED) {
1063 res = mDevice->ops->release_stream(mDevice, mId);
1064 if (res != OK) {
1065 ALOGE("%s: Unable to release stream %d",
1066 __FUNCTION__, mId);
1067 return res;
1068 }
1069 }
1070 if (mState >= CONNECTED) {
1071 res = native_window_api_disconnect(mConsumerInterface.get(),
1072 NATIVE_WINDOW_API_CAMERA);
1073 if (res != OK) {
1074 ALOGE("%s: Unable to disconnect stream %d from native window",
1075 __FUNCTION__, mId);
1076 return res;
1077 }
1078 }
1079 mId = -1;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001080 mState = RELEASED;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001081 return OK;
1082}
1083
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001084status_t Camera2Device::StreamAdapter::setTransform(int transform) {
1085 status_t res;
1086 if (mState < CONNECTED) {
1087 ALOGE("%s: Cannot set transform on unconnected stream", __FUNCTION__);
1088 return INVALID_OPERATION;
1089 }
1090 res = native_window_set_buffers_transform(mConsumerInterface.get(),
1091 transform);
1092 if (res != OK) {
1093 ALOGE("%s: Unable to configure stream transform to %x: %s (%d)",
1094 __FUNCTION__, transform, strerror(-res), res);
1095 }
1096 return res;
1097}
1098
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001099status_t Camera2Device::StreamAdapter::dump(int fd,
1100 const Vector<String16>& args) {
1101 String8 result = String8::format(" Stream %d: %d x %d, format 0x%x\n",
1102 mId, mWidth, mHeight, mFormat);
1103 result.appendFormat(" size %d, usage 0x%x, requested format 0x%x\n",
1104 mSize, mUsage, mFormatRequested);
1105 result.appendFormat(" total buffers: %d, dequeued buffers: %d\n",
1106 mTotalBuffers, mActiveBuffers);
1107 result.appendFormat(" frame count: %d, last timestamp %lld\n",
1108 mFrameCount, mLastTimestamp);
1109 write(fd, result.string(), result.size());
1110 return OK;
1111}
1112
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001113const camera2_stream_ops *Camera2Device::StreamAdapter::getStreamOps() {
1114 return static_cast<camera2_stream_ops *>(this);
1115}
1116
1117ANativeWindow* Camera2Device::StreamAdapter::toANW(
1118 const camera2_stream_ops_t *w) {
1119 return static_cast<const StreamAdapter*>(w)->mConsumerInterface.get();
1120}
1121
1122int Camera2Device::StreamAdapter::dequeue_buffer(const camera2_stream_ops_t *w,
1123 buffer_handle_t** buffer) {
1124 int res;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001125 StreamAdapter* stream =
1126 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
1127 if (stream->mState != ACTIVE) {
1128 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001129 return INVALID_OPERATION;
1130 }
1131
1132 ANativeWindow *a = toANW(w);
1133 ANativeWindowBuffer* anb;
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001134 res = native_window_dequeue_buffer_and_wait(a, &anb);
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001135 if (res != OK) {
1136 ALOGE("Stream %d dequeue: Error from native_window: %s (%d)", stream->mId,
1137 strerror(-res), res);
1138 return res;
1139 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001140
1141 *buffer = &(anb->handle);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001142 stream->mActiveBuffers++;
1143
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001144 ALOGVV("Stream %d dequeue: Buffer %p dequeued", stream->mId, (void*)(**buffer));
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001145 return res;
1146}
1147
1148int Camera2Device::StreamAdapter::enqueue_buffer(const camera2_stream_ops_t* w,
1149 int64_t timestamp,
1150 buffer_handle_t* buffer) {
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001151 StreamAdapter *stream =
1152 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001153 stream->mFrameCount++;
1154 ALOGVV("Stream %d enqueue: Frame %d (%p) captured at %lld ns",
James Dong6638f3b2012-09-05 16:46:36 -07001155 stream->mId, stream->mFrameCount, (void*)(*buffer), timestamp);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001156 int state = stream->mState;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001157 if (state != ACTIVE) {
1158 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1159 return INVALID_OPERATION;
1160 }
1161 ANativeWindow *a = toANW(w);
1162 status_t err;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001163
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001164 err = native_window_set_buffers_timestamp(a, timestamp);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001165 if (err != OK) {
1166 ALOGE("%s: Error setting timestamp on native window: %s (%d)",
1167 __FUNCTION__, strerror(-err), err);
1168 return err;
1169 }
1170 err = a->queueBuffer(a,
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001171 container_of(buffer, ANativeWindowBuffer, handle), -1);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001172 if (err != OK) {
1173 ALOGE("%s: Error queueing buffer to native window: %s (%d)",
1174 __FUNCTION__, strerror(-err), err);
James Dong31d377b2012-08-09 17:43:46 -07001175 return err;
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001176 }
James Dong31d377b2012-08-09 17:43:46 -07001177
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001178 stream->mActiveBuffers--;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001179 stream->mLastTimestamp = timestamp;
James Dong31d377b2012-08-09 17:43:46 -07001180 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001181}
1182
1183int Camera2Device::StreamAdapter::cancel_buffer(const camera2_stream_ops_t* w,
1184 buffer_handle_t* buffer) {
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001185 StreamAdapter *stream =
1186 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001187 ALOGVV("Stream %d cancel: Buffer %p",
1188 stream->mId, (void*)(*buffer));
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001189 if (stream->mState != ACTIVE) {
1190 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001191 return INVALID_OPERATION;
1192 }
James Dong31d377b2012-08-09 17:43:46 -07001193
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001194 ANativeWindow *a = toANW(w);
James Dong31d377b2012-08-09 17:43:46 -07001195 int err = a->cancelBuffer(a,
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001196 container_of(buffer, ANativeWindowBuffer, handle), -1);
James Dong31d377b2012-08-09 17:43:46 -07001197 if (err != OK) {
1198 ALOGE("%s: Error canceling buffer to native window: %s (%d)",
1199 __FUNCTION__, strerror(-err), err);
1200 return err;
1201 }
1202
1203 stream->mActiveBuffers--;
1204 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001205}
1206
1207int Camera2Device::StreamAdapter::set_crop(const camera2_stream_ops_t* w,
1208 int left, int top, int right, int bottom) {
1209 int state = static_cast<const StreamAdapter*>(w)->mState;
1210 if (state != ACTIVE) {
1211 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1212 return INVALID_OPERATION;
1213 }
1214 ANativeWindow *a = toANW(w);
1215 android_native_rect_t crop = { left, top, right, bottom };
1216 return native_window_set_crop(a, &crop);
1217}
1218
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -07001219/**
1220 * Camera2Device::ReprocessStreamAdapter
1221 */
1222
1223#ifndef container_of
1224#define container_of(ptr, type, member) \
1225 (type *)((char*)(ptr) - offsetof(type, member))
1226#endif
1227
1228Camera2Device::ReprocessStreamAdapter::ReprocessStreamAdapter(camera2_device_t *d):
1229 mState(RELEASED),
1230 mDevice(d),
1231 mId(-1),
1232 mWidth(0), mHeight(0), mFormat(0),
1233 mActiveBuffers(0),
1234 mFrameCount(0)
1235{
1236 camera2_stream_in_ops::acquire_buffer = acquire_buffer;
1237 camera2_stream_in_ops::release_buffer = release_buffer;
1238}
1239
1240Camera2Device::ReprocessStreamAdapter::~ReprocessStreamAdapter() {
1241 if (mState != RELEASED) {
1242 release();
1243 }
1244}
1245
1246status_t Camera2Device::ReprocessStreamAdapter::connectToDevice(
1247 const sp<StreamAdapter> &outputStream) {
1248 status_t res;
1249 ALOGV("%s: E", __FUNCTION__);
1250
1251 if (mState != RELEASED) return INVALID_OPERATION;
1252 if (outputStream == NULL) {
1253 ALOGE("%s: Null base stream passed to reprocess stream adapter",
1254 __FUNCTION__);
1255 return BAD_VALUE;
1256 }
1257
1258 mBaseStream = outputStream;
1259 mWidth = outputStream->getWidth();
1260 mHeight = outputStream->getHeight();
1261 mFormat = outputStream->getFormat();
1262
1263 ALOGV("%s: New reprocess stream parameters %d x %d, format 0x%x",
1264 __FUNCTION__, mWidth, mHeight, mFormat);
1265
1266 // Allocate device-side stream interface
1267
1268 uint32_t id;
1269 res = mDevice->ops->allocate_reprocess_stream_from_stream(mDevice,
1270 outputStream->getId(), getStreamOps(),
1271 &id);
1272 if (res != OK) {
1273 ALOGE("%s: Device reprocess stream allocation failed: %s (%d)",
1274 __FUNCTION__, strerror(-res), res);
1275 return res;
1276 }
1277
1278 ALOGV("%s: Allocated reprocess stream id %d based on stream %d",
1279 __FUNCTION__, id, outputStream->getId());
1280
1281 mId = id;
1282
1283 mState = ACTIVE;
1284
1285 return OK;
1286}
1287
1288status_t Camera2Device::ReprocessStreamAdapter::release() {
1289 status_t res;
1290 ALOGV("%s: Releasing stream %d", __FUNCTION__, mId);
1291 if (mState >= ACTIVE) {
1292 res = mDevice->ops->release_reprocess_stream(mDevice, mId);
1293 if (res != OK) {
1294 ALOGE("%s: Unable to release stream %d",
1295 __FUNCTION__, mId);
1296 return res;
1297 }
1298 }
1299
1300 List<QueueEntry>::iterator s;
1301 for (s = mQueue.begin(); s != mQueue.end(); s++) {
1302 sp<BufferReleasedListener> listener = s->releaseListener.promote();
1303 if (listener != 0) listener->onBufferReleased(s->handle);
1304 }
1305 for (s = mInFlightQueue.begin(); s != mInFlightQueue.end(); s++) {
1306 sp<BufferReleasedListener> listener = s->releaseListener.promote();
1307 if (listener != 0) listener->onBufferReleased(s->handle);
1308 }
1309 mQueue.clear();
1310 mInFlightQueue.clear();
1311
1312 mState = RELEASED;
1313 return OK;
1314}
1315
1316status_t Camera2Device::ReprocessStreamAdapter::pushIntoStream(
1317 buffer_handle_t *handle, const wp<BufferReleasedListener> &releaseListener) {
1318 // TODO: Some error checking here would be nice
1319 ALOGV("%s: Pushing buffer %p to stream", __FUNCTION__, (void*)(*handle));
1320
1321 QueueEntry entry;
1322 entry.handle = handle;
1323 entry.releaseListener = releaseListener;
1324 mQueue.push_back(entry);
1325 return OK;
1326}
1327
1328status_t Camera2Device::ReprocessStreamAdapter::dump(int fd,
1329 const Vector<String16>& args) {
1330 String8 result =
1331 String8::format(" Reprocess stream %d: %d x %d, fmt 0x%x\n",
1332 mId, mWidth, mHeight, mFormat);
1333 result.appendFormat(" acquired buffers: %d\n",
1334 mActiveBuffers);
1335 result.appendFormat(" frame count: %d\n",
1336 mFrameCount);
1337 write(fd, result.string(), result.size());
1338 return OK;
1339}
1340
1341const camera2_stream_in_ops *Camera2Device::ReprocessStreamAdapter::getStreamOps() {
1342 return static_cast<camera2_stream_in_ops *>(this);
1343}
1344
1345int Camera2Device::ReprocessStreamAdapter::acquire_buffer(
1346 const camera2_stream_in_ops_t *w,
1347 buffer_handle_t** buffer) {
1348 int res;
1349 ReprocessStreamAdapter* stream =
1350 const_cast<ReprocessStreamAdapter*>(
1351 static_cast<const ReprocessStreamAdapter*>(w));
1352 if (stream->mState != ACTIVE) {
1353 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
1354 return INVALID_OPERATION;
1355 }
1356
1357 if (stream->mQueue.empty()) {
1358 *buffer = NULL;
1359 return OK;
1360 }
1361
1362 QueueEntry &entry = *(stream->mQueue.begin());
1363
1364 *buffer = entry.handle;
1365
1366 stream->mInFlightQueue.push_back(entry);
1367 stream->mQueue.erase(stream->mQueue.begin());
1368
1369 stream->mActiveBuffers++;
1370
1371 ALOGV("Stream %d acquire: Buffer %p acquired", stream->mId,
1372 (void*)(**buffer));
1373 return OK;
1374}
1375
1376int Camera2Device::ReprocessStreamAdapter::release_buffer(
1377 const camera2_stream_in_ops_t* w,
1378 buffer_handle_t* buffer) {
1379 ReprocessStreamAdapter *stream =
1380 const_cast<ReprocessStreamAdapter*>(
1381 static_cast<const ReprocessStreamAdapter*>(w) );
1382 stream->mFrameCount++;
1383 ALOGV("Reprocess stream %d release: Frame %d (%p)",
1384 stream->mId, stream->mFrameCount, (void*)*buffer);
1385 int state = stream->mState;
1386 if (state != ACTIVE) {
1387 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1388 return INVALID_OPERATION;
1389 }
1390 stream->mActiveBuffers--;
1391
1392 List<QueueEntry>::iterator s;
1393 for (s = stream->mInFlightQueue.begin(); s != stream->mInFlightQueue.end(); s++) {
1394 if ( s->handle == buffer ) break;
1395 }
1396 if (s == stream->mInFlightQueue.end()) {
1397 ALOGE("%s: Can't find buffer %p in in-flight list!", __FUNCTION__,
1398 buffer);
1399 return INVALID_OPERATION;
1400 }
1401
1402 sp<BufferReleasedListener> listener = s->releaseListener.promote();
1403 if (listener != 0) {
1404 listener->onBufferReleased(s->handle);
1405 } else {
1406 ALOGE("%s: Can't free buffer - missing listener", __FUNCTION__);
1407 }
1408 stream->mInFlightQueue.erase(s);
1409
1410 return OK;
1411}
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001412
1413}; // namespace android