blob: a171c46b50e956688f98318710d1c24138af826b [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 Talvalac8474b62012-08-24 16:30:44 -070041 ALOGV("%s: Shutting down device for camera %d", __FUNCTION__, mId);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070042 if (mDevice) {
43 status_t res;
44 res = mDevice->common.close(&mDevice->common);
45 if (res != OK) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070046 ALOGE("%s: Could not close camera %d: %s (%d)",
47 __FUNCTION__,
48 mId, strerror(-res), res);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070049 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070050 mDevice = NULL;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070051 }
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -070052 ALOGV("%s: Shutdown complete", __FUNCTION__);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070053}
54
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070055status_t Camera2Device::initialize(camera_module_t *module)
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070056{
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -070057 ALOGV("%s: Initializing device for camera %d", __FUNCTION__, mId);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -070058
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070059 status_t res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070060 char name[10];
61 snprintf(name, sizeof(name), "%d", mId);
62
63 res = module->common.methods->open(&module->common, name,
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070064 reinterpret_cast<hw_device_t**>(&mDevice));
65
66 if (res != OK) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070067 ALOGE("%s: Could not open camera %d: %s (%d)", __FUNCTION__,
68 mId, strerror(-res), res);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070069 return res;
70 }
71
72 if (mDevice->common.version != CAMERA_DEVICE_API_VERSION_2_0) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070073 ALOGE("%s: Could not open camera %d: "
74 "Camera device is not version %x, reports %x instead",
75 __FUNCTION__, mId, CAMERA_DEVICE_API_VERSION_2_0,
76 mDevice->common.version);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070077 return BAD_VALUE;
78 }
79
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070080 camera_info info;
81 res = module->get_camera_info(mId, &info);
82 if (res != OK ) return res;
83
84 if (info.device_version != mDevice->common.version) {
85 ALOGE("%s: HAL reporting mismatched camera_info version (%x)"
86 " and device version (%x).", __FUNCTION__,
87 mDevice->common.version, info.device_version);
88 return BAD_VALUE;
89 }
90
91 mDeviceInfo = info.static_camera_characteristics;
92
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -070093 res = mRequestQueue.setConsumerDevice(mDevice);
94 if (res != OK) {
95 ALOGE("%s: Camera %d: Unable to connect request queue to device: %s (%d)",
96 __FUNCTION__, mId, strerror(-res), res);
97 return res;
98 }
99 res = mFrameQueue.setProducerDevice(mDevice);
100 if (res != OK) {
101 ALOGE("%s: Camera %d: Unable to connect frame queue to device: %s (%d)",
102 __FUNCTION__, mId, strerror(-res), res);
103 return res;
104 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700105
106 res = mDevice->ops->get_metadata_vendor_tag_ops(mDevice, &mVendorTagOps);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700107 if (res != OK ) {
108 ALOGE("%s: Camera %d: Unable to retrieve tag ops from device: %s (%d)",
109 __FUNCTION__, mId, strerror(-res), res);
110 return res;
111 }
Shuzhen Wang092fe442012-08-31 10:24:22 -0700112 res = set_camera_metadata_vendor_tag_ops(mVendorTagOps);
113 if (res != OK) {
114 ALOGE("%s: Camera %d: Unable to set tag ops: %s (%d)",
115 __FUNCTION__, mId, strerror(-res), res);
116 return res;
117 }
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700118 setNotifyCallback(NULL);
119
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700120 return OK;
121}
122
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700123status_t Camera2Device::dump(int fd, const Vector<String16>& args) {
124
125 String8 result;
Eino-Ville Talvala97197152012-08-06 14:25:19 -0700126 int detailLevel = 0;
127 int n = args.size();
128 String16 detailOption("-d");
129 for (int i = 0; i + 1 < n; i++) {
130 if (args[i] == detailOption) {
131 String8 levelStr(args[i+1]);
132 detailLevel = atoi(levelStr.string());
133 }
134 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700135
Eino-Ville Talvala603b12e2012-08-08 09:25:58 -0700136 result.appendFormat(" Camera2Device[%d] dump (detail level %d):\n",
137 mId, detailLevel);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700138
Eino-Ville Talvala97197152012-08-06 14:25:19 -0700139 if (detailLevel > 0) {
140 result = " Request queue contents:\n";
141 write(fd, result.string(), result.size());
142 mRequestQueue.dump(fd, args);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700143
Eino-Ville Talvala97197152012-08-06 14:25:19 -0700144 result = " Frame queue contents:\n";
145 write(fd, result.string(), result.size());
146 mFrameQueue.dump(fd, args);
147 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700148
149 result = " Active streams:\n";
150 write(fd, result.string(), result.size());
151 for (StreamList::iterator s = mStreams.begin(); s != mStreams.end(); s++) {
152 (*s)->dump(fd, args);
153 }
154
155 result = " HAL device dump:\n";
156 write(fd, result.string(), result.size());
157
158 status_t res;
159 res = mDevice->ops->dump(mDevice, fd);
160
161 return res;
162}
163
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700164const camera2::CameraMetadata& Camera2Device::info() const {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700165 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700166
167 return mDeviceInfo;
168}
169
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700170status_t Camera2Device::capture(CameraMetadata &request) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700171 ALOGV("%s: E", __FUNCTION__);
172
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700173 mRequestQueue.enqueue(request.release());
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700174 return OK;
175}
176
177
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700178status_t Camera2Device::setStreamingRequest(const CameraMetadata &request) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700179 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700180 CameraMetadata streamRequest(request);
181 return mRequestQueue.setStreamSlot(streamRequest.release());
182}
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700183
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700184status_t Camera2Device::clearStreamingRequest() {
185 return mRequestQueue.setStreamSlot(NULL);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700186}
187
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700188status_t Camera2Device::createStream(sp<ANativeWindow> consumer,
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700189 uint32_t width, uint32_t height, int format, size_t size, int *id) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700190 status_t res;
191 ALOGV("%s: E", __FUNCTION__);
192
193 sp<StreamAdapter> stream = new StreamAdapter(mDevice);
194
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700195 res = stream->connectToDevice(consumer, width, height, format, size);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700196 if (res != OK) {
197 ALOGE("%s: Camera %d: Unable to create stream (%d x %d, format %x):"
198 "%s (%d)",
199 __FUNCTION__, mId, width, height, format, strerror(-res), res);
200 return res;
201 }
202
203 *id = stream->getId();
204
205 mStreams.push_back(stream);
206 return OK;
207}
208
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700209status_t Camera2Device::createReprocessStreamFromStream(int outputId, int *id) {
210 status_t res;
211 ALOGV("%s: E", __FUNCTION__);
212
213 bool found = false;
214 StreamList::iterator streamI;
215 for (streamI = mStreams.begin();
216 streamI != mStreams.end(); streamI++) {
217 if ((*streamI)->getId() == outputId) {
218 found = true;
219 break;
220 }
221 }
222 if (!found) {
223 ALOGE("%s: Camera %d: Output stream %d doesn't exist; can't create "
224 "reprocess stream from it!", __FUNCTION__, mId, outputId);
225 return BAD_VALUE;
226 }
227
228 sp<ReprocessStreamAdapter> stream = new ReprocessStreamAdapter(mDevice);
229
230 res = stream->connectToDevice((*streamI));
231 if (res != OK) {
232 ALOGE("%s: Camera %d: Unable to create reprocessing stream from "\
233 "stream %d: %s (%d)", __FUNCTION__, mId, outputId,
234 strerror(-res), res);
235 return res;
236 }
237
238 *id = stream->getId();
239
240 mReprocessStreams.push_back(stream);
241 return OK;
242}
243
244
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700245status_t Camera2Device::getStreamInfo(int id,
246 uint32_t *width, uint32_t *height, uint32_t *format) {
247 ALOGV("%s: E", __FUNCTION__);
248 bool found = false;
249 StreamList::iterator streamI;
250 for (streamI = mStreams.begin();
251 streamI != mStreams.end(); streamI++) {
252 if ((*streamI)->getId() == id) {
253 found = true;
254 break;
255 }
256 }
257 if (!found) {
258 ALOGE("%s: Camera %d: Stream %d does not exist",
259 __FUNCTION__, mId, id);
260 return BAD_VALUE;
261 }
262
263 if (width) *width = (*streamI)->getWidth();
264 if (height) *height = (*streamI)->getHeight();
265 if (format) *format = (*streamI)->getFormat();
266
267 return OK;
268}
269
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -0700270status_t Camera2Device::setStreamTransform(int id,
271 int transform) {
272 ALOGV("%s: E", __FUNCTION__);
273 bool found = false;
274 StreamList::iterator streamI;
275 for (streamI = mStreams.begin();
276 streamI != mStreams.end(); streamI++) {
277 if ((*streamI)->getId() == id) {
278 found = true;
279 break;
280 }
281 }
282 if (!found) {
283 ALOGE("%s: Camera %d: Stream %d does not exist",
284 __FUNCTION__, mId, id);
285 return BAD_VALUE;
286 }
287
288 return (*streamI)->setTransform(transform);
289}
290
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700291status_t Camera2Device::deleteStream(int id) {
292 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700293 bool found = false;
294 for (StreamList::iterator streamI = mStreams.begin();
295 streamI != mStreams.end(); streamI++) {
296 if ((*streamI)->getId() == id) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700297 status_t res = (*streamI)->release();
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700298 if (res != OK) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700299 ALOGE("%s: Unable to release stream %d from HAL device: "
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700300 "%s (%d)", __FUNCTION__, id, strerror(-res), res);
301 return res;
302 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700303 mStreams.erase(streamI);
304 found = true;
305 break;
306 }
307 }
308 if (!found) {
309 ALOGE("%s: Camera %d: Unable to find stream %d to delete",
310 __FUNCTION__, mId, id);
311 return BAD_VALUE;
312 }
313 return OK;
314}
315
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700316status_t Camera2Device::deleteReprocessStream(int id) {
317 ALOGV("%s: E", __FUNCTION__);
318 bool found = false;
319 for (ReprocessStreamList::iterator streamI = mReprocessStreams.begin();
320 streamI != mReprocessStreams.end(); streamI++) {
321 if ((*streamI)->getId() == id) {
322 status_t res = (*streamI)->release();
323 if (res != OK) {
324 ALOGE("%s: Unable to release reprocess stream %d from "
325 "HAL device: %s (%d)", __FUNCTION__, id,
326 strerror(-res), res);
327 return res;
328 }
329 mReprocessStreams.erase(streamI);
330 found = true;
331 break;
332 }
333 }
334 if (!found) {
335 ALOGE("%s: Camera %d: Unable to find stream %d to delete",
336 __FUNCTION__, mId, id);
337 return BAD_VALUE;
338 }
339 return OK;
340}
341
342
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700343status_t Camera2Device::createDefaultRequest(int templateId,
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700344 CameraMetadata *request) {
345 status_t err;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700346 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700347 camera_metadata_t *rawRequest;
348 err = mDevice->ops->construct_default_request(
349 mDevice, templateId, &rawRequest);
350 request->acquire(rawRequest);
351 return err;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700352}
353
354status_t Camera2Device::waitUntilDrained() {
355 static const uint32_t kSleepTime = 50000; // 50 ms
356 static const uint32_t kMaxSleepTime = 10000000; // 10 s
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700357 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700358 if (mRequestQueue.getBufferCount() ==
359 CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS) return INVALID_OPERATION;
360
361 // TODO: Set up notifications from HAL, instead of sleeping here
362 uint32_t totalTime = 0;
363 while (mDevice->ops->get_in_progress_count(mDevice) > 0) {
364 usleep(kSleepTime);
365 totalTime += kSleepTime;
366 if (totalTime > kMaxSleepTime) {
367 ALOGE("%s: Waited %d us, requests still in flight", __FUNCTION__,
368 totalTime);
369 return TIMED_OUT;
370 }
371 }
372 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700373}
374
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700375status_t Camera2Device::setNotifyCallback(NotificationListener *listener) {
376 status_t res;
377 res = mDevice->ops->set_notify_callback(mDevice, notificationCallback,
378 reinterpret_cast<void*>(listener) );
379 if (res != OK) {
380 ALOGE("%s: Unable to set notification callback!", __FUNCTION__);
381 }
382 return res;
383}
384
385void Camera2Device::notificationCallback(int32_t msg_type,
386 int32_t ext1,
387 int32_t ext2,
388 int32_t ext3,
389 void *user) {
390 NotificationListener *listener = reinterpret_cast<NotificationListener*>(user);
391 ALOGV("%s: Notification %d, arguments %d, %d, %d", __FUNCTION__, msg_type,
392 ext1, ext2, ext3);
393 if (listener != NULL) {
394 switch (msg_type) {
395 case CAMERA2_MSG_ERROR:
396 listener->notifyError(ext1, ext2, ext3);
397 break;
398 case CAMERA2_MSG_SHUTTER: {
399 nsecs_t timestamp = (nsecs_t)ext2 | ((nsecs_t)(ext3) << 32 );
400 listener->notifyShutter(ext1, timestamp);
401 break;
402 }
403 case CAMERA2_MSG_AUTOFOCUS:
404 listener->notifyAutoFocus(ext1, ext2);
405 break;
406 case CAMERA2_MSG_AUTOEXPOSURE:
407 listener->notifyAutoExposure(ext1, ext2);
408 break;
409 case CAMERA2_MSG_AUTOWB:
410 listener->notifyAutoWhitebalance(ext1, ext2);
411 break;
412 default:
413 ALOGE("%s: Unknown notification %d (arguments %d, %d, %d)!",
414 __FUNCTION__, msg_type, ext1, ext2, ext3);
415 }
416 }
417}
418
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -0700419status_t Camera2Device::waitForNextFrame(nsecs_t timeout) {
420 return mFrameQueue.waitForBuffer(timeout);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700421}
422
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700423status_t Camera2Device::getNextFrame(CameraMetadata *frame) {
424 status_t res;
425 camera_metadata_t *rawFrame;
426 res = mFrameQueue.dequeue(&rawFrame);
427 if (rawFrame == NULL) {
428 return NOT_ENOUGH_DATA;
429 } else if (res == OK) {
430 frame->acquire(rawFrame);
431 }
432 return res;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700433}
434
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700435status_t Camera2Device::triggerAutofocus(uint32_t id) {
436 status_t res;
437 ALOGV("%s: Triggering autofocus, id %d", __FUNCTION__, id);
438 res = mDevice->ops->trigger_action(mDevice,
439 CAMERA2_TRIGGER_AUTOFOCUS, id, 0);
440 if (res != OK) {
441 ALOGE("%s: Error triggering autofocus (id %d)",
442 __FUNCTION__, id);
443 }
444 return res;
445}
446
447status_t Camera2Device::triggerCancelAutofocus(uint32_t id) {
448 status_t res;
449 ALOGV("%s: Canceling autofocus, id %d", __FUNCTION__, id);
450 res = mDevice->ops->trigger_action(mDevice,
451 CAMERA2_TRIGGER_CANCEL_AUTOFOCUS, id, 0);
452 if (res != OK) {
453 ALOGE("%s: Error canceling autofocus (id %d)",
454 __FUNCTION__, id);
455 }
456 return res;
457}
458
459status_t Camera2Device::triggerPrecaptureMetering(uint32_t id) {
460 status_t res;
461 ALOGV("%s: Triggering precapture metering, id %d", __FUNCTION__, id);
462 res = mDevice->ops->trigger_action(mDevice,
463 CAMERA2_TRIGGER_PRECAPTURE_METERING, id, 0);
464 if (res != OK) {
465 ALOGE("%s: Error triggering precapture metering (id %d)",
466 __FUNCTION__, id);
467 }
468 return res;
469}
470
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700471status_t Camera2Device::pushReprocessBuffer(int reprocessStreamId,
472 buffer_handle_t *buffer, wp<BufferReleasedListener> listener) {
473 ALOGV("%s: E", __FUNCTION__);
474 bool found = false;
475 status_t res = OK;
476 for (ReprocessStreamList::iterator streamI = mReprocessStreams.begin();
477 streamI != mReprocessStreams.end(); streamI++) {
478 if ((*streamI)->getId() == reprocessStreamId) {
479 res = (*streamI)->pushIntoStream(buffer, listener);
480 if (res != OK) {
481 ALOGE("%s: Unable to push buffer to reprocess stream %d: %s (%d)",
482 __FUNCTION__, reprocessStreamId, strerror(-res), res);
483 return res;
484 }
485 found = true;
486 break;
487 }
488 }
489 if (!found) {
490 ALOGE("%s: Camera %d: Unable to find reprocess stream %d",
491 __FUNCTION__, mId, reprocessStreamId);
492 res = BAD_VALUE;
493 }
494 return res;
495}
496
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700497/**
498 * Camera2Device::NotificationListener
499 */
500
501Camera2Device::NotificationListener::~NotificationListener() {
502}
503
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700504/**
505 * Camera2Device::MetadataQueue
506 */
507
508Camera2Device::MetadataQueue::MetadataQueue():
509 mDevice(NULL),
510 mFrameCount(0),
511 mCount(0),
512 mStreamSlotCount(0),
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -0700513 mSignalConsumer(true)
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700514{
515 camera2_request_queue_src_ops::dequeue_request = consumer_dequeue;
516 camera2_request_queue_src_ops::request_count = consumer_buffer_count;
517 camera2_request_queue_src_ops::free_request = consumer_free;
518
519 camera2_frame_queue_dst_ops::dequeue_frame = producer_dequeue;
520 camera2_frame_queue_dst_ops::cancel_frame = producer_cancel;
521 camera2_frame_queue_dst_ops::enqueue_frame = producer_enqueue;
522}
523
524Camera2Device::MetadataQueue::~MetadataQueue() {
525 Mutex::Autolock l(mMutex);
526 freeBuffers(mEntries.begin(), mEntries.end());
527 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
528}
529
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700530// Connect to camera2 HAL as consumer (input requests/reprocessing)
531status_t Camera2Device::MetadataQueue::setConsumerDevice(camera2_device_t *d) {
532 status_t res;
533 res = d->ops->set_request_queue_src_ops(d,
534 this);
535 if (res != OK) return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700536 mDevice = d;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700537 return OK;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700538}
539
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700540status_t Camera2Device::MetadataQueue::setProducerDevice(camera2_device_t *d) {
541 status_t res;
542 res = d->ops->set_frame_queue_dst_ops(d,
543 this);
544 return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700545}
546
547// Real interfaces
548status_t Camera2Device::MetadataQueue::enqueue(camera_metadata_t *buf) {
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700549 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700550 Mutex::Autolock l(mMutex);
551
552 mCount++;
553 mEntries.push_back(buf);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700554
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700555 return signalConsumerLocked();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700556}
557
558int Camera2Device::MetadataQueue::getBufferCount() {
559 Mutex::Autolock l(mMutex);
560 if (mStreamSlotCount > 0) {
561 return CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS;
562 }
563 return mCount;
564}
565
566status_t Camera2Device::MetadataQueue::dequeue(camera_metadata_t **buf,
567 bool incrementCount)
568{
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700569 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700570 status_t res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700571 Mutex::Autolock l(mMutex);
572
573 if (mCount == 0) {
574 if (mStreamSlotCount == 0) {
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700575 ALOGVV("%s: Empty", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700576 *buf = NULL;
577 mSignalConsumer = true;
578 return OK;
579 }
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700580 ALOGVV("%s: Streaming %d frames to queue", __FUNCTION__,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700581 mStreamSlotCount);
582
583 for (List<camera_metadata_t*>::iterator slotEntry = mStreamSlot.begin();
584 slotEntry != mStreamSlot.end();
585 slotEntry++ ) {
586 size_t entries = get_camera_metadata_entry_count(*slotEntry);
587 size_t dataBytes = get_camera_metadata_data_count(*slotEntry);
588
589 camera_metadata_t *copy =
590 allocate_camera_metadata(entries, dataBytes);
591 append_camera_metadata(copy, *slotEntry);
592 mEntries.push_back(copy);
593 }
594 mCount = mStreamSlotCount;
595 }
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700596 ALOGVV("MetadataQueue: deque (%d buffers)", mCount);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700597 camera_metadata_t *b = *(mEntries.begin());
598 mEntries.erase(mEntries.begin());
599
600 if (incrementCount) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700601 camera_metadata_entry_t frameCount;
602 res = find_camera_metadata_entry(b,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700603 ANDROID_REQUEST_FRAME_COUNT,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700604 &frameCount);
605 if (res != OK) {
606 ALOGE("%s: Unable to add frame count: %s (%d)",
607 __FUNCTION__, strerror(-res), res);
608 } else {
609 *frameCount.data.i32 = mFrameCount;
610 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700611 mFrameCount++;
612 }
613
614 *buf = b;
615 mCount--;
616
617 return OK;
618}
619
620status_t Camera2Device::MetadataQueue::waitForBuffer(nsecs_t timeout)
621{
622 Mutex::Autolock l(mMutex);
623 status_t res;
624 while (mCount == 0) {
625 res = notEmpty.waitRelative(mMutex,timeout);
626 if (res != OK) return res;
627 }
628 return OK;
629}
630
631status_t Camera2Device::MetadataQueue::setStreamSlot(camera_metadata_t *buf)
632{
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700633 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700634 Mutex::Autolock l(mMutex);
635 if (buf == NULL) {
636 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
637 mStreamSlotCount = 0;
638 return OK;
639 }
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700640 camera_metadata_t *buf2 = clone_camera_metadata(buf);
641 if (!buf2) {
642 ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__);
643 return NO_MEMORY;
644 }
645
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700646 if (mStreamSlotCount > 1) {
647 List<camera_metadata_t*>::iterator deleter = ++mStreamSlot.begin();
648 freeBuffers(++mStreamSlot.begin(), mStreamSlot.end());
649 mStreamSlotCount = 1;
650 }
651 if (mStreamSlotCount == 1) {
652 free_camera_metadata( *(mStreamSlot.begin()) );
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700653 *(mStreamSlot.begin()) = buf2;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700654 } else {
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700655 mStreamSlot.push_front(buf2);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700656 mStreamSlotCount = 1;
657 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700658 return signalConsumerLocked();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700659}
660
661status_t Camera2Device::MetadataQueue::setStreamSlot(
662 const List<camera_metadata_t*> &bufs)
663{
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700664 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700665 Mutex::Autolock l(mMutex);
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700666 status_t res;
667
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700668 if (mStreamSlotCount > 0) {
669 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
670 }
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700671 mStreamSlotCount = 0;
672 for (List<camera_metadata_t*>::const_iterator r = bufs.begin();
673 r != bufs.end(); r++) {
674 camera_metadata_t *r2 = clone_camera_metadata(*r);
675 if (!r2) {
676 ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__);
677 return NO_MEMORY;
678 }
679 mStreamSlot.push_back(r2);
680 mStreamSlotCount++;
681 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700682 return signalConsumerLocked();
683}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700684
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700685status_t Camera2Device::MetadataQueue::dump(int fd,
686 const Vector<String16>& args) {
687 String8 result;
688 status_t notLocked;
689 notLocked = mMutex.tryLock();
690 if (notLocked) {
691 result.append(" (Unable to lock queue mutex)\n");
692 }
693 result.appendFormat(" Current frame number: %d\n", mFrameCount);
694 if (mStreamSlotCount == 0) {
695 result.append(" Stream slot: Empty\n");
696 write(fd, result.string(), result.size());
697 } else {
698 result.appendFormat(" Stream slot: %d entries\n",
699 mStreamSlot.size());
700 int i = 0;
701 for (List<camera_metadata_t*>::iterator r = mStreamSlot.begin();
702 r != mStreamSlot.end(); r++) {
703 result = String8::format(" Stream slot buffer %d:\n", i);
704 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700705 dump_indented_camera_metadata(*r, fd, 2, 10);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700706 i++;
707 }
708 }
709 if (mEntries.size() == 0) {
710 result = " Main queue is empty\n";
711 write(fd, result.string(), result.size());
712 } else {
713 result = String8::format(" Main queue has %d entries:\n",
714 mEntries.size());
715 int i = 0;
716 for (List<camera_metadata_t*>::iterator r = mEntries.begin();
717 r != mEntries.end(); r++) {
718 result = String8::format(" Queue entry %d:\n", i);
719 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700720 dump_indented_camera_metadata(*r, fd, 2, 10);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700721 i++;
722 }
723 }
724
725 if (notLocked == 0) {
726 mMutex.unlock();
727 }
728
729 return OK;
730}
731
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700732status_t Camera2Device::MetadataQueue::signalConsumerLocked() {
733 status_t res = OK;
734 notEmpty.signal();
735 if (mSignalConsumer && mDevice != NULL) {
736 mSignalConsumer = false;
737
738 mMutex.unlock();
739 ALOGV("%s: Signaling consumer", __FUNCTION__);
740 res = mDevice->ops->notify_request_queue_not_empty(mDevice);
741 mMutex.lock();
742 }
743 return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700744}
745
746status_t Camera2Device::MetadataQueue::freeBuffers(
747 List<camera_metadata_t*>::iterator start,
748 List<camera_metadata_t*>::iterator end)
749{
750 while (start != end) {
751 free_camera_metadata(*start);
752 start = mStreamSlot.erase(start);
753 }
754 return OK;
755}
756
757Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
758 const camera2_request_queue_src_ops_t *q)
759{
760 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
761 return const_cast<MetadataQueue*>(cmq);
762}
763
764Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
765 const camera2_frame_queue_dst_ops_t *q)
766{
767 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
768 return const_cast<MetadataQueue*>(cmq);
769}
770
771int Camera2Device::MetadataQueue::consumer_buffer_count(
772 const camera2_request_queue_src_ops_t *q)
773{
774 MetadataQueue *queue = getInstance(q);
775 return queue->getBufferCount();
776}
777
778int Camera2Device::MetadataQueue::consumer_dequeue(
779 const camera2_request_queue_src_ops_t *q,
780 camera_metadata_t **buffer)
781{
782 MetadataQueue *queue = getInstance(q);
783 return queue->dequeue(buffer, true);
784}
785
786int Camera2Device::MetadataQueue::consumer_free(
787 const camera2_request_queue_src_ops_t *q,
788 camera_metadata_t *old_buffer)
789{
790 MetadataQueue *queue = getInstance(q);
791 free_camera_metadata(old_buffer);
792 return OK;
793}
794
795int Camera2Device::MetadataQueue::producer_dequeue(
796 const camera2_frame_queue_dst_ops_t *q,
797 size_t entries, size_t bytes,
798 camera_metadata_t **buffer)
799{
800 camera_metadata_t *new_buffer =
801 allocate_camera_metadata(entries, bytes);
802 if (new_buffer == NULL) return NO_MEMORY;
803 *buffer = new_buffer;
804 return OK;
805}
806
807int Camera2Device::MetadataQueue::producer_cancel(
808 const camera2_frame_queue_dst_ops_t *q,
809 camera_metadata_t *old_buffer)
810{
811 free_camera_metadata(old_buffer);
812 return OK;
813}
814
815int Camera2Device::MetadataQueue::producer_enqueue(
816 const camera2_frame_queue_dst_ops_t *q,
817 camera_metadata_t *filled_buffer)
818{
819 MetadataQueue *queue = getInstance(q);
820 return queue->enqueue(filled_buffer);
821}
822
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700823/**
824 * Camera2Device::StreamAdapter
825 */
826
827#ifndef container_of
828#define container_of(ptr, type, member) \
829 (type *)((char*)(ptr) - offsetof(type, member))
830#endif
831
832Camera2Device::StreamAdapter::StreamAdapter(camera2_device_t *d):
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700833 mState(RELEASED),
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700834 mDevice(d),
835 mId(-1),
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700836 mWidth(0), mHeight(0), mFormat(0), mSize(0), mUsage(0),
837 mMaxProducerBuffers(0), mMaxConsumerBuffers(0),
838 mTotalBuffers(0),
839 mFormatRequested(0),
840 mActiveBuffers(0),
841 mFrameCount(0),
842 mLastTimestamp(0)
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700843{
844 camera2_stream_ops::dequeue_buffer = dequeue_buffer;
845 camera2_stream_ops::enqueue_buffer = enqueue_buffer;
846 camera2_stream_ops::cancel_buffer = cancel_buffer;
847 camera2_stream_ops::set_crop = set_crop;
848}
849
850Camera2Device::StreamAdapter::~StreamAdapter() {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700851 if (mState != RELEASED) {
852 release();
853 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700854}
855
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700856status_t Camera2Device::StreamAdapter::connectToDevice(
857 sp<ANativeWindow> consumer,
858 uint32_t width, uint32_t height, int format, size_t size) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700859 status_t res;
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700860 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700861
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700862 if (mState != RELEASED) return INVALID_OPERATION;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700863 if (consumer == NULL) {
864 ALOGE("%s: Null consumer passed to stream adapter", __FUNCTION__);
865 return BAD_VALUE;
866 }
867
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700868 ALOGV("%s: New stream parameters %d x %d, format 0x%x, size %d",
869 __FUNCTION__, width, height, format, size);
870
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700871 mConsumerInterface = consumer;
872 mWidth = width;
873 mHeight = height;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700874 mSize = (format == HAL_PIXEL_FORMAT_BLOB) ? size : 0;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700875 mFormatRequested = format;
876
877 // Allocate device-side stream interface
878
879 uint32_t id;
880 uint32_t formatActual;
881 uint32_t usage;
882 uint32_t maxBuffers = 2;
883 res = mDevice->ops->allocate_stream(mDevice,
884 mWidth, mHeight, mFormatRequested, getStreamOps(),
885 &id, &formatActual, &usage, &maxBuffers);
886 if (res != OK) {
887 ALOGE("%s: Device stream allocation failed: %s (%d)",
888 __FUNCTION__, strerror(-res), res);
889 return res;
890 }
891
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700892 ALOGV("%s: Allocated stream id %d, actual format 0x%x, "
893 "usage 0x%x, producer wants %d buffers", __FUNCTION__,
894 id, formatActual, usage, maxBuffers);
895
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700896 mId = id;
897 mFormat = formatActual;
898 mUsage = usage;
899 mMaxProducerBuffers = maxBuffers;
900
901 mState = ALLOCATED;
902
903 // Configure consumer-side ANativeWindow interface
904 res = native_window_api_connect(mConsumerInterface.get(),
905 NATIVE_WINDOW_API_CAMERA);
906 if (res != OK) {
907 ALOGE("%s: Unable to connect to native window for stream %d",
908 __FUNCTION__, mId);
909
910 return res;
911 }
912
913 mState = CONNECTED;
914
915 res = native_window_set_usage(mConsumerInterface.get(), mUsage);
916 if (res != OK) {
917 ALOGE("%s: Unable to configure usage %08x for stream %d",
918 __FUNCTION__, mUsage, mId);
919 return res;
920 }
921
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -0700922 res = native_window_set_scaling_mode(mConsumerInterface.get(),
923 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
924 if (res != OK) {
925 ALOGE("%s: Unable to configure stream scaling: %s (%d)",
926 __FUNCTION__, strerror(-res), res);
927 return res;
928 }
929
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -0700930 res = setTransform(0);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -0700931 if (res != OK) {
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -0700932 return res;
933 }
934
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700935 if (mFormat == HAL_PIXEL_FORMAT_BLOB) {
936 res = native_window_set_buffers_geometry(mConsumerInterface.get(),
937 mSize, 1, mFormat);
938 if (res != OK) {
939 ALOGE("%s: Unable to configure compressed stream buffer geometry"
940 " %d x %d, size %d for stream %d",
941 __FUNCTION__, mWidth, mHeight, mSize, mId);
942 return res;
943 }
944 } else {
945 res = native_window_set_buffers_geometry(mConsumerInterface.get(),
946 mWidth, mHeight, mFormat);
947 if (res != OK) {
948 ALOGE("%s: Unable to configure stream buffer geometry"
949 " %d x %d, format 0x%x for stream %d",
950 __FUNCTION__, mWidth, mHeight, mFormat, mId);
951 return res;
952 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700953 }
954
955 int maxConsumerBuffers;
956 res = mConsumerInterface->query(mConsumerInterface.get(),
957 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &maxConsumerBuffers);
958 if (res != OK) {
959 ALOGE("%s: Unable to query consumer undequeued"
960 " buffer count for stream %d", __FUNCTION__, mId);
961 return res;
962 }
963 mMaxConsumerBuffers = maxConsumerBuffers;
964
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700965 ALOGV("%s: Consumer wants %d buffers", __FUNCTION__,
966 mMaxConsumerBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700967
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700968 mTotalBuffers = mMaxConsumerBuffers + mMaxProducerBuffers;
969 mActiveBuffers = 0;
970 mFrameCount = 0;
971 mLastTimestamp = 0;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700972
973 res = native_window_set_buffer_count(mConsumerInterface.get(),
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700974 mTotalBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700975 if (res != OK) {
976 ALOGE("%s: Unable to set buffer count for stream %d",
977 __FUNCTION__, mId);
978 return res;
979 }
980
981 // Register allocated buffers with HAL device
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700982 buffer_handle_t *buffers = new buffer_handle_t[mTotalBuffers];
983 ANativeWindowBuffer **anwBuffers = new ANativeWindowBuffer*[mTotalBuffers];
984 uint32_t bufferIdx = 0;
985 for (; bufferIdx < mTotalBuffers; bufferIdx++) {
Jamie Gennis1e5b2b32012-06-13 16:29:51 -0700986 res = native_window_dequeue_buffer_and_wait(mConsumerInterface.get(),
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700987 &anwBuffers[bufferIdx]);
988 if (res != OK) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700989 ALOGE("%s: Unable to dequeue buffer %d for initial registration for "
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700990 "stream %d", __FUNCTION__, bufferIdx, mId);
991 goto cleanUpBuffers;
992 }
993
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700994 buffers[bufferIdx] = anwBuffers[bufferIdx]->handle;
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700995 ALOGV("%s: Buffer %p allocated", __FUNCTION__, (void*)buffers[bufferIdx]);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700996 }
997
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -0700998 ALOGV("%s: Registering %d buffers with camera HAL", __FUNCTION__, mTotalBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700999 res = mDevice->ops->register_stream_buffers(mDevice,
1000 mId,
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001001 mTotalBuffers,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001002 buffers);
1003 if (res != OK) {
1004 ALOGE("%s: Unable to register buffers with HAL device for stream %d",
1005 __FUNCTION__, mId);
1006 } else {
1007 mState = ACTIVE;
1008 }
1009
1010cleanUpBuffers:
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001011 ALOGV("%s: Cleaning up %d buffers", __FUNCTION__, bufferIdx);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001012 for (uint32_t i = 0; i < bufferIdx; i++) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001013 res = mConsumerInterface->cancelBuffer(mConsumerInterface.get(),
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001014 anwBuffers[i], -1);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001015 if (res != OK) {
1016 ALOGE("%s: Unable to cancel buffer %d after registration",
1017 __FUNCTION__, i);
1018 }
1019 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001020 delete[] anwBuffers;
1021 delete[] buffers;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001022
1023 return res;
1024}
1025
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001026status_t Camera2Device::StreamAdapter::release() {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001027 status_t res;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001028 ALOGV("%s: Releasing stream %d", __FUNCTION__, mId);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001029 if (mState >= ALLOCATED) {
1030 res = mDevice->ops->release_stream(mDevice, mId);
1031 if (res != OK) {
1032 ALOGE("%s: Unable to release stream %d",
1033 __FUNCTION__, mId);
1034 return res;
1035 }
1036 }
1037 if (mState >= CONNECTED) {
1038 res = native_window_api_disconnect(mConsumerInterface.get(),
1039 NATIVE_WINDOW_API_CAMERA);
1040 if (res != OK) {
1041 ALOGE("%s: Unable to disconnect stream %d from native window",
1042 __FUNCTION__, mId);
1043 return res;
1044 }
1045 }
1046 mId = -1;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001047 mState = RELEASED;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001048 return OK;
1049}
1050
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001051status_t Camera2Device::StreamAdapter::setTransform(int transform) {
1052 status_t res;
1053 if (mState < CONNECTED) {
1054 ALOGE("%s: Cannot set transform on unconnected stream", __FUNCTION__);
1055 return INVALID_OPERATION;
1056 }
1057 res = native_window_set_buffers_transform(mConsumerInterface.get(),
1058 transform);
1059 if (res != OK) {
1060 ALOGE("%s: Unable to configure stream transform to %x: %s (%d)",
1061 __FUNCTION__, transform, strerror(-res), res);
1062 }
1063 return res;
1064}
1065
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001066status_t Camera2Device::StreamAdapter::dump(int fd,
1067 const Vector<String16>& args) {
1068 String8 result = String8::format(" Stream %d: %d x %d, format 0x%x\n",
1069 mId, mWidth, mHeight, mFormat);
1070 result.appendFormat(" size %d, usage 0x%x, requested format 0x%x\n",
1071 mSize, mUsage, mFormatRequested);
1072 result.appendFormat(" total buffers: %d, dequeued buffers: %d\n",
1073 mTotalBuffers, mActiveBuffers);
1074 result.appendFormat(" frame count: %d, last timestamp %lld\n",
1075 mFrameCount, mLastTimestamp);
1076 write(fd, result.string(), result.size());
1077 return OK;
1078}
1079
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001080const camera2_stream_ops *Camera2Device::StreamAdapter::getStreamOps() {
1081 return static_cast<camera2_stream_ops *>(this);
1082}
1083
1084ANativeWindow* Camera2Device::StreamAdapter::toANW(
1085 const camera2_stream_ops_t *w) {
1086 return static_cast<const StreamAdapter*>(w)->mConsumerInterface.get();
1087}
1088
1089int Camera2Device::StreamAdapter::dequeue_buffer(const camera2_stream_ops_t *w,
1090 buffer_handle_t** buffer) {
1091 int res;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001092 StreamAdapter* stream =
1093 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
1094 if (stream->mState != ACTIVE) {
1095 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001096 return INVALID_OPERATION;
1097 }
1098
1099 ANativeWindow *a = toANW(w);
1100 ANativeWindowBuffer* anb;
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001101 res = native_window_dequeue_buffer_and_wait(a, &anb);
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001102 if (res != OK) {
1103 ALOGE("Stream %d dequeue: Error from native_window: %s (%d)", stream->mId,
1104 strerror(-res), res);
1105 return res;
1106 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001107
1108 *buffer = &(anb->handle);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001109 stream->mActiveBuffers++;
1110
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001111 ALOGVV("Stream %d dequeue: Buffer %p dequeued", stream->mId, (void*)(**buffer));
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001112 return res;
1113}
1114
1115int Camera2Device::StreamAdapter::enqueue_buffer(const camera2_stream_ops_t* w,
1116 int64_t timestamp,
1117 buffer_handle_t* buffer) {
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001118 StreamAdapter *stream =
1119 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001120 stream->mFrameCount++;
1121 ALOGVV("Stream %d enqueue: Frame %d (%p) captured at %lld ns",
James Dong6638f3b2012-09-05 16:46:36 -07001122 stream->mId, stream->mFrameCount, (void*)(*buffer), timestamp);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001123 int state = stream->mState;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001124 if (state != ACTIVE) {
1125 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1126 return INVALID_OPERATION;
1127 }
1128 ANativeWindow *a = toANW(w);
1129 status_t err;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001130
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001131 err = native_window_set_buffers_timestamp(a, timestamp);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001132 if (err != OK) {
1133 ALOGE("%s: Error setting timestamp on native window: %s (%d)",
1134 __FUNCTION__, strerror(-err), err);
1135 return err;
1136 }
1137 err = a->queueBuffer(a,
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001138 container_of(buffer, ANativeWindowBuffer, handle), -1);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001139 if (err != OK) {
1140 ALOGE("%s: Error queueing buffer to native window: %s (%d)",
1141 __FUNCTION__, strerror(-err), err);
James Dong31d377b2012-08-09 17:43:46 -07001142 return err;
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001143 }
James Dong31d377b2012-08-09 17:43:46 -07001144
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001145 stream->mActiveBuffers--;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001146 stream->mLastTimestamp = timestamp;
James Dong31d377b2012-08-09 17:43:46 -07001147 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001148}
1149
1150int Camera2Device::StreamAdapter::cancel_buffer(const camera2_stream_ops_t* w,
1151 buffer_handle_t* buffer) {
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001152 StreamAdapter *stream =
1153 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001154 ALOGVV("Stream %d cancel: Buffer %p",
1155 stream->mId, (void*)(*buffer));
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001156 if (stream->mState != ACTIVE) {
1157 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001158 return INVALID_OPERATION;
1159 }
James Dong31d377b2012-08-09 17:43:46 -07001160
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001161 ANativeWindow *a = toANW(w);
James Dong31d377b2012-08-09 17:43:46 -07001162 int err = a->cancelBuffer(a,
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001163 container_of(buffer, ANativeWindowBuffer, handle), -1);
James Dong31d377b2012-08-09 17:43:46 -07001164 if (err != OK) {
1165 ALOGE("%s: Error canceling buffer to native window: %s (%d)",
1166 __FUNCTION__, strerror(-err), err);
1167 return err;
1168 }
1169
1170 stream->mActiveBuffers--;
1171 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001172}
1173
1174int Camera2Device::StreamAdapter::set_crop(const camera2_stream_ops_t* w,
1175 int left, int top, int right, int bottom) {
1176 int state = static_cast<const StreamAdapter*>(w)->mState;
1177 if (state != ACTIVE) {
1178 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1179 return INVALID_OPERATION;
1180 }
1181 ANativeWindow *a = toANW(w);
1182 android_native_rect_t crop = { left, top, right, bottom };
1183 return native_window_set_crop(a, &crop);
1184}
1185
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -07001186/**
1187 * Camera2Device::ReprocessStreamAdapter
1188 */
1189
1190#ifndef container_of
1191#define container_of(ptr, type, member) \
1192 (type *)((char*)(ptr) - offsetof(type, member))
1193#endif
1194
1195Camera2Device::ReprocessStreamAdapter::ReprocessStreamAdapter(camera2_device_t *d):
1196 mState(RELEASED),
1197 mDevice(d),
1198 mId(-1),
1199 mWidth(0), mHeight(0), mFormat(0),
1200 mActiveBuffers(0),
1201 mFrameCount(0)
1202{
1203 camera2_stream_in_ops::acquire_buffer = acquire_buffer;
1204 camera2_stream_in_ops::release_buffer = release_buffer;
1205}
1206
1207Camera2Device::ReprocessStreamAdapter::~ReprocessStreamAdapter() {
1208 if (mState != RELEASED) {
1209 release();
1210 }
1211}
1212
1213status_t Camera2Device::ReprocessStreamAdapter::connectToDevice(
1214 const sp<StreamAdapter> &outputStream) {
1215 status_t res;
1216 ALOGV("%s: E", __FUNCTION__);
1217
1218 if (mState != RELEASED) return INVALID_OPERATION;
1219 if (outputStream == NULL) {
1220 ALOGE("%s: Null base stream passed to reprocess stream adapter",
1221 __FUNCTION__);
1222 return BAD_VALUE;
1223 }
1224
1225 mBaseStream = outputStream;
1226 mWidth = outputStream->getWidth();
1227 mHeight = outputStream->getHeight();
1228 mFormat = outputStream->getFormat();
1229
1230 ALOGV("%s: New reprocess stream parameters %d x %d, format 0x%x",
1231 __FUNCTION__, mWidth, mHeight, mFormat);
1232
1233 // Allocate device-side stream interface
1234
1235 uint32_t id;
1236 res = mDevice->ops->allocate_reprocess_stream_from_stream(mDevice,
1237 outputStream->getId(), getStreamOps(),
1238 &id);
1239 if (res != OK) {
1240 ALOGE("%s: Device reprocess stream allocation failed: %s (%d)",
1241 __FUNCTION__, strerror(-res), res);
1242 return res;
1243 }
1244
1245 ALOGV("%s: Allocated reprocess stream id %d based on stream %d",
1246 __FUNCTION__, id, outputStream->getId());
1247
1248 mId = id;
1249
1250 mState = ACTIVE;
1251
1252 return OK;
1253}
1254
1255status_t Camera2Device::ReprocessStreamAdapter::release() {
1256 status_t res;
1257 ALOGV("%s: Releasing stream %d", __FUNCTION__, mId);
1258 if (mState >= ACTIVE) {
1259 res = mDevice->ops->release_reprocess_stream(mDevice, mId);
1260 if (res != OK) {
1261 ALOGE("%s: Unable to release stream %d",
1262 __FUNCTION__, mId);
1263 return res;
1264 }
1265 }
1266
1267 List<QueueEntry>::iterator s;
1268 for (s = mQueue.begin(); s != mQueue.end(); s++) {
1269 sp<BufferReleasedListener> listener = s->releaseListener.promote();
1270 if (listener != 0) listener->onBufferReleased(s->handle);
1271 }
1272 for (s = mInFlightQueue.begin(); s != mInFlightQueue.end(); s++) {
1273 sp<BufferReleasedListener> listener = s->releaseListener.promote();
1274 if (listener != 0) listener->onBufferReleased(s->handle);
1275 }
1276 mQueue.clear();
1277 mInFlightQueue.clear();
1278
1279 mState = RELEASED;
1280 return OK;
1281}
1282
1283status_t Camera2Device::ReprocessStreamAdapter::pushIntoStream(
1284 buffer_handle_t *handle, const wp<BufferReleasedListener> &releaseListener) {
1285 // TODO: Some error checking here would be nice
1286 ALOGV("%s: Pushing buffer %p to stream", __FUNCTION__, (void*)(*handle));
1287
1288 QueueEntry entry;
1289 entry.handle = handle;
1290 entry.releaseListener = releaseListener;
1291 mQueue.push_back(entry);
1292 return OK;
1293}
1294
1295status_t Camera2Device::ReprocessStreamAdapter::dump(int fd,
1296 const Vector<String16>& args) {
1297 String8 result =
1298 String8::format(" Reprocess stream %d: %d x %d, fmt 0x%x\n",
1299 mId, mWidth, mHeight, mFormat);
1300 result.appendFormat(" acquired buffers: %d\n",
1301 mActiveBuffers);
1302 result.appendFormat(" frame count: %d\n",
1303 mFrameCount);
1304 write(fd, result.string(), result.size());
1305 return OK;
1306}
1307
1308const camera2_stream_in_ops *Camera2Device::ReprocessStreamAdapter::getStreamOps() {
1309 return static_cast<camera2_stream_in_ops *>(this);
1310}
1311
1312int Camera2Device::ReprocessStreamAdapter::acquire_buffer(
1313 const camera2_stream_in_ops_t *w,
1314 buffer_handle_t** buffer) {
1315 int res;
1316 ReprocessStreamAdapter* stream =
1317 const_cast<ReprocessStreamAdapter*>(
1318 static_cast<const ReprocessStreamAdapter*>(w));
1319 if (stream->mState != ACTIVE) {
1320 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
1321 return INVALID_OPERATION;
1322 }
1323
1324 if (stream->mQueue.empty()) {
1325 *buffer = NULL;
1326 return OK;
1327 }
1328
1329 QueueEntry &entry = *(stream->mQueue.begin());
1330
1331 *buffer = entry.handle;
1332
1333 stream->mInFlightQueue.push_back(entry);
1334 stream->mQueue.erase(stream->mQueue.begin());
1335
1336 stream->mActiveBuffers++;
1337
1338 ALOGV("Stream %d acquire: Buffer %p acquired", stream->mId,
1339 (void*)(**buffer));
1340 return OK;
1341}
1342
1343int Camera2Device::ReprocessStreamAdapter::release_buffer(
1344 const camera2_stream_in_ops_t* w,
1345 buffer_handle_t* buffer) {
1346 ReprocessStreamAdapter *stream =
1347 const_cast<ReprocessStreamAdapter*>(
1348 static_cast<const ReprocessStreamAdapter*>(w) );
1349 stream->mFrameCount++;
1350 ALOGV("Reprocess stream %d release: Frame %d (%p)",
1351 stream->mId, stream->mFrameCount, (void*)*buffer);
1352 int state = stream->mState;
1353 if (state != ACTIVE) {
1354 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1355 return INVALID_OPERATION;
1356 }
1357 stream->mActiveBuffers--;
1358
1359 List<QueueEntry>::iterator s;
1360 for (s = stream->mInFlightQueue.begin(); s != stream->mInFlightQueue.end(); s++) {
1361 if ( s->handle == buffer ) break;
1362 }
1363 if (s == stream->mInFlightQueue.end()) {
1364 ALOGE("%s: Can't find buffer %p in in-flight list!", __FUNCTION__,
1365 buffer);
1366 return INVALID_OPERATION;
1367 }
1368
1369 sp<BufferReleasedListener> listener = s->releaseListener.promote();
1370 if (listener != 0) {
1371 listener->onBufferReleased(s->handle);
1372 } else {
1373 ALOGE("%s: Can't free buffer - missing listener", __FUNCTION__);
1374 }
1375 stream->mInFlightQueue.erase(s);
1376
1377 return OK;
1378}
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001379
1380}; // namespace android