blob: f42e3a5b498954ae3eec8937a4e489528d52b3bd [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 Talvala6db981c2012-05-21 18:54:30 -070036 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070037}
38
39Camera2Device::~Camera2Device()
40{
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -070041 ALOGV("%s: E", __FUNCTION__);
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 }
52}
53
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070054status_t Camera2Device::initialize(camera_module_t *module)
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070055{
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -070056 ALOGV("%s: E", __FUNCTION__);
57
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070058 status_t res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070059 char name[10];
60 snprintf(name, sizeof(name), "%d", mId);
61
62 res = module->common.methods->open(&module->common, name,
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070063 reinterpret_cast<hw_device_t**>(&mDevice));
64
65 if (res != OK) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070066 ALOGE("%s: Could not open camera %d: %s (%d)", __FUNCTION__,
67 mId, strerror(-res), res);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070068 return res;
69 }
70
71 if (mDevice->common.version != CAMERA_DEVICE_API_VERSION_2_0) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070072 ALOGE("%s: Could not open camera %d: "
73 "Camera device is not version %x, reports %x instead",
74 __FUNCTION__, mId, CAMERA_DEVICE_API_VERSION_2_0,
75 mDevice->common.version);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070076 return BAD_VALUE;
77 }
78
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070079 camera_info info;
80 res = module->get_camera_info(mId, &info);
81 if (res != OK ) return res;
82
83 if (info.device_version != mDevice->common.version) {
84 ALOGE("%s: HAL reporting mismatched camera_info version (%x)"
85 " and device version (%x).", __FUNCTION__,
86 mDevice->common.version, info.device_version);
87 return BAD_VALUE;
88 }
89
90 mDeviceInfo = info.static_camera_characteristics;
91
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -070092 res = mRequestQueue.setConsumerDevice(mDevice);
93 if (res != OK) {
94 ALOGE("%s: Camera %d: Unable to connect request queue to device: %s (%d)",
95 __FUNCTION__, mId, strerror(-res), res);
96 return res;
97 }
98 res = mFrameQueue.setProducerDevice(mDevice);
99 if (res != OK) {
100 ALOGE("%s: Camera %d: Unable to connect frame queue to device: %s (%d)",
101 __FUNCTION__, mId, strerror(-res), res);
102 return res;
103 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700104
105 res = mDevice->ops->get_metadata_vendor_tag_ops(mDevice, &mVendorTagOps);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700106 if (res != OK ) {
107 ALOGE("%s: Camera %d: Unable to retrieve tag ops from device: %s (%d)",
108 __FUNCTION__, mId, strerror(-res), res);
109 return res;
110 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700111
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700112 return OK;
113}
114
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700115status_t Camera2Device::dump(int fd, const Vector<String16>& args) {
116
117 String8 result;
118
119 result.appendFormat(" Camera2Device[%d] dump:\n", mId);
120
121 result.appendFormat(" Static camera information metadata:\n");
122 write(fd, result.string(), result.size());
123 dump_camera_metadata(mDeviceInfo, fd, 2);
124
125 result = " Request queue contents:\n";
126 write(fd, result.string(), result.size());
127 mRequestQueue.dump(fd, args);
128
129 result = " Frame queue contents:\n";
130 write(fd, result.string(), result.size());
131 mFrameQueue.dump(fd, args);
132
133 result = " Active streams:\n";
134 write(fd, result.string(), result.size());
135 for (StreamList::iterator s = mStreams.begin(); s != mStreams.end(); s++) {
136 (*s)->dump(fd, args);
137 }
138
139 result = " HAL device dump:\n";
140 write(fd, result.string(), result.size());
141
142 status_t res;
143 res = mDevice->ops->dump(mDevice, fd);
144
145 return res;
146}
147
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700148camera_metadata_t *Camera2Device::info() {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700149 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700150
151 return mDeviceInfo;
152}
153
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700154status_t Camera2Device::capture(camera_metadata_t* request) {
155 ALOGV("%s: E", __FUNCTION__);
156
157 mRequestQueue.enqueue(request);
158 return OK;
159}
160
161
162status_t Camera2Device::setStreamingRequest(camera_metadata_t* request) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700163 ALOGV("%s: E", __FUNCTION__);
164
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700165 mRequestQueue.setStreamSlot(request);
166 return OK;
167}
168
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700169status_t Camera2Device::createStream(sp<ANativeWindow> consumer,
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700170 uint32_t width, uint32_t height, int format, size_t size, int *id) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700171 status_t res;
172 ALOGV("%s: E", __FUNCTION__);
173
174 sp<StreamAdapter> stream = new StreamAdapter(mDevice);
175
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700176 res = stream->connectToDevice(consumer, width, height, format, size);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700177 if (res != OK) {
178 ALOGE("%s: Camera %d: Unable to create stream (%d x %d, format %x):"
179 "%s (%d)",
180 __FUNCTION__, mId, width, height, format, strerror(-res), res);
181 return res;
182 }
183
184 *id = stream->getId();
185
186 mStreams.push_back(stream);
187 return OK;
188}
189
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700190status_t Camera2Device::getStreamInfo(int id,
191 uint32_t *width, uint32_t *height, uint32_t *format) {
192 ALOGV("%s: E", __FUNCTION__);
193 bool found = false;
194 StreamList::iterator streamI;
195 for (streamI = mStreams.begin();
196 streamI != mStreams.end(); streamI++) {
197 if ((*streamI)->getId() == id) {
198 found = true;
199 break;
200 }
201 }
202 if (!found) {
203 ALOGE("%s: Camera %d: Stream %d does not exist",
204 __FUNCTION__, mId, id);
205 return BAD_VALUE;
206 }
207
208 if (width) *width = (*streamI)->getWidth();
209 if (height) *height = (*streamI)->getHeight();
210 if (format) *format = (*streamI)->getFormat();
211
212 return OK;
213}
214
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -0700215status_t Camera2Device::setStreamTransform(int id,
216 int transform) {
217 ALOGV("%s: E", __FUNCTION__);
218 bool found = false;
219 StreamList::iterator streamI;
220 for (streamI = mStreams.begin();
221 streamI != mStreams.end(); streamI++) {
222 if ((*streamI)->getId() == id) {
223 found = true;
224 break;
225 }
226 }
227 if (!found) {
228 ALOGE("%s: Camera %d: Stream %d does not exist",
229 __FUNCTION__, mId, id);
230 return BAD_VALUE;
231 }
232
233 return (*streamI)->setTransform(transform);
234}
235
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700236status_t Camera2Device::deleteStream(int id) {
237 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700238 bool found = false;
239 for (StreamList::iterator streamI = mStreams.begin();
240 streamI != mStreams.end(); streamI++) {
241 if ((*streamI)->getId() == id) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700242 status_t res = (*streamI)->release();
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700243 if (res != OK) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700244 ALOGE("%s: Unable to release stream %d from HAL device: "
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700245 "%s (%d)", __FUNCTION__, id, strerror(-res), res);
246 return res;
247 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700248 mStreams.erase(streamI);
249 found = true;
250 break;
251 }
252 }
253 if (!found) {
254 ALOGE("%s: Camera %d: Unable to find stream %d to delete",
255 __FUNCTION__, mId, id);
256 return BAD_VALUE;
257 }
258 return OK;
259}
260
261status_t Camera2Device::createDefaultRequest(int templateId,
262 camera_metadata_t **request) {
263 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700264 return mDevice->ops->construct_default_request(
265 mDevice, templateId, request);
266}
267
268status_t Camera2Device::waitUntilDrained() {
269 static const uint32_t kSleepTime = 50000; // 50 ms
270 static const uint32_t kMaxSleepTime = 10000000; // 10 s
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700271 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700272 if (mRequestQueue.getBufferCount() ==
273 CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS) return INVALID_OPERATION;
274
275 // TODO: Set up notifications from HAL, instead of sleeping here
276 uint32_t totalTime = 0;
277 while (mDevice->ops->get_in_progress_count(mDevice) > 0) {
278 usleep(kSleepTime);
279 totalTime += kSleepTime;
280 if (totalTime > kMaxSleepTime) {
281 ALOGE("%s: Waited %d us, requests still in flight", __FUNCTION__,
282 totalTime);
283 return TIMED_OUT;
284 }
285 }
286 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700287}
288
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700289/**
290 * Camera2Device::MetadataQueue
291 */
292
293Camera2Device::MetadataQueue::MetadataQueue():
294 mDevice(NULL),
295 mFrameCount(0),
296 mCount(0),
297 mStreamSlotCount(0),
298 mSignalConsumer(true)
299{
300 camera2_request_queue_src_ops::dequeue_request = consumer_dequeue;
301 camera2_request_queue_src_ops::request_count = consumer_buffer_count;
302 camera2_request_queue_src_ops::free_request = consumer_free;
303
304 camera2_frame_queue_dst_ops::dequeue_frame = producer_dequeue;
305 camera2_frame_queue_dst_ops::cancel_frame = producer_cancel;
306 camera2_frame_queue_dst_ops::enqueue_frame = producer_enqueue;
307}
308
309Camera2Device::MetadataQueue::~MetadataQueue() {
310 Mutex::Autolock l(mMutex);
311 freeBuffers(mEntries.begin(), mEntries.end());
312 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
313}
314
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700315// Connect to camera2 HAL as consumer (input requests/reprocessing)
316status_t Camera2Device::MetadataQueue::setConsumerDevice(camera2_device_t *d) {
317 status_t res;
318 res = d->ops->set_request_queue_src_ops(d,
319 this);
320 if (res != OK) return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700321 mDevice = d;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700322 return OK;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700323}
324
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700325status_t Camera2Device::MetadataQueue::setProducerDevice(camera2_device_t *d) {
326 status_t res;
327 res = d->ops->set_frame_queue_dst_ops(d,
328 this);
329 return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700330}
331
332// Real interfaces
333status_t Camera2Device::MetadataQueue::enqueue(camera_metadata_t *buf) {
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700334 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700335 Mutex::Autolock l(mMutex);
336
337 mCount++;
338 mEntries.push_back(buf);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700339
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700340 return signalConsumerLocked();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700341}
342
343int Camera2Device::MetadataQueue::getBufferCount() {
344 Mutex::Autolock l(mMutex);
345 if (mStreamSlotCount > 0) {
346 return CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS;
347 }
348 return mCount;
349}
350
351status_t Camera2Device::MetadataQueue::dequeue(camera_metadata_t **buf,
352 bool incrementCount)
353{
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700354 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700355 status_t res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700356 Mutex::Autolock l(mMutex);
357
358 if (mCount == 0) {
359 if (mStreamSlotCount == 0) {
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700360 ALOGVV("%s: Empty", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700361 *buf = NULL;
362 mSignalConsumer = true;
363 return OK;
364 }
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700365 ALOGVV("%s: Streaming %d frames to queue", __FUNCTION__,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700366 mStreamSlotCount);
367
368 for (List<camera_metadata_t*>::iterator slotEntry = mStreamSlot.begin();
369 slotEntry != mStreamSlot.end();
370 slotEntry++ ) {
371 size_t entries = get_camera_metadata_entry_count(*slotEntry);
372 size_t dataBytes = get_camera_metadata_data_count(*slotEntry);
373
374 camera_metadata_t *copy =
375 allocate_camera_metadata(entries, dataBytes);
376 append_camera_metadata(copy, *slotEntry);
377 mEntries.push_back(copy);
378 }
379 mCount = mStreamSlotCount;
380 }
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700381 ALOGVV("MetadataQueue: deque (%d buffers)", mCount);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700382 camera_metadata_t *b = *(mEntries.begin());
383 mEntries.erase(mEntries.begin());
384
385 if (incrementCount) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700386 camera_metadata_entry_t frameCount;
387 res = find_camera_metadata_entry(b,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700388 ANDROID_REQUEST_FRAME_COUNT,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700389 &frameCount);
390 if (res != OK) {
391 ALOGE("%s: Unable to add frame count: %s (%d)",
392 __FUNCTION__, strerror(-res), res);
393 } else {
394 *frameCount.data.i32 = mFrameCount;
395 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700396 mFrameCount++;
397 }
398
399 *buf = b;
400 mCount--;
401
402 return OK;
403}
404
405status_t Camera2Device::MetadataQueue::waitForBuffer(nsecs_t timeout)
406{
407 Mutex::Autolock l(mMutex);
408 status_t res;
409 while (mCount == 0) {
410 res = notEmpty.waitRelative(mMutex,timeout);
411 if (res != OK) return res;
412 }
413 return OK;
414}
415
416status_t Camera2Device::MetadataQueue::setStreamSlot(camera_metadata_t *buf)
417{
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700418 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700419 Mutex::Autolock l(mMutex);
420 if (buf == NULL) {
421 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
422 mStreamSlotCount = 0;
423 return OK;
424 }
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700425 camera_metadata_t *buf2 = clone_camera_metadata(buf);
426 if (!buf2) {
427 ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__);
428 return NO_MEMORY;
429 }
430
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700431 if (mStreamSlotCount > 1) {
432 List<camera_metadata_t*>::iterator deleter = ++mStreamSlot.begin();
433 freeBuffers(++mStreamSlot.begin(), mStreamSlot.end());
434 mStreamSlotCount = 1;
435 }
436 if (mStreamSlotCount == 1) {
437 free_camera_metadata( *(mStreamSlot.begin()) );
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700438 *(mStreamSlot.begin()) = buf2;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700439 } else {
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700440 mStreamSlot.push_front(buf2);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700441 mStreamSlotCount = 1;
442 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700443 return signalConsumerLocked();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700444}
445
446status_t Camera2Device::MetadataQueue::setStreamSlot(
447 const List<camera_metadata_t*> &bufs)
448{
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700449 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700450 Mutex::Autolock l(mMutex);
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700451 status_t res;
452
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700453 if (mStreamSlotCount > 0) {
454 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
455 }
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700456 mStreamSlotCount = 0;
457 for (List<camera_metadata_t*>::const_iterator r = bufs.begin();
458 r != bufs.end(); r++) {
459 camera_metadata_t *r2 = clone_camera_metadata(*r);
460 if (!r2) {
461 ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__);
462 return NO_MEMORY;
463 }
464 mStreamSlot.push_back(r2);
465 mStreamSlotCount++;
466 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700467 return signalConsumerLocked();
468}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700469
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700470status_t Camera2Device::MetadataQueue::dump(int fd,
471 const Vector<String16>& args) {
472 String8 result;
473 status_t notLocked;
474 notLocked = mMutex.tryLock();
475 if (notLocked) {
476 result.append(" (Unable to lock queue mutex)\n");
477 }
478 result.appendFormat(" Current frame number: %d\n", mFrameCount);
479 if (mStreamSlotCount == 0) {
480 result.append(" Stream slot: Empty\n");
481 write(fd, result.string(), result.size());
482 } else {
483 result.appendFormat(" Stream slot: %d entries\n",
484 mStreamSlot.size());
485 int i = 0;
486 for (List<camera_metadata_t*>::iterator r = mStreamSlot.begin();
487 r != mStreamSlot.end(); r++) {
488 result = String8::format(" Stream slot buffer %d:\n", i);
489 write(fd, result.string(), result.size());
490 dump_camera_metadata(*r, fd, 2);
491 i++;
492 }
493 }
494 if (mEntries.size() == 0) {
495 result = " Main queue is empty\n";
496 write(fd, result.string(), result.size());
497 } else {
498 result = String8::format(" Main queue has %d entries:\n",
499 mEntries.size());
500 int i = 0;
501 for (List<camera_metadata_t*>::iterator r = mEntries.begin();
502 r != mEntries.end(); r++) {
503 result = String8::format(" Queue entry %d:\n", i);
504 write(fd, result.string(), result.size());
505 dump_camera_metadata(*r, fd, 2);
506 i++;
507 }
508 }
509
510 if (notLocked == 0) {
511 mMutex.unlock();
512 }
513
514 return OK;
515}
516
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700517status_t Camera2Device::MetadataQueue::signalConsumerLocked() {
518 status_t res = OK;
519 notEmpty.signal();
520 if (mSignalConsumer && mDevice != NULL) {
521 mSignalConsumer = false;
522
523 mMutex.unlock();
524 ALOGV("%s: Signaling consumer", __FUNCTION__);
525 res = mDevice->ops->notify_request_queue_not_empty(mDevice);
526 mMutex.lock();
527 }
528 return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700529}
530
531status_t Camera2Device::MetadataQueue::freeBuffers(
532 List<camera_metadata_t*>::iterator start,
533 List<camera_metadata_t*>::iterator end)
534{
535 while (start != end) {
536 free_camera_metadata(*start);
537 start = mStreamSlot.erase(start);
538 }
539 return OK;
540}
541
542Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
543 const camera2_request_queue_src_ops_t *q)
544{
545 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
546 return const_cast<MetadataQueue*>(cmq);
547}
548
549Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
550 const camera2_frame_queue_dst_ops_t *q)
551{
552 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
553 return const_cast<MetadataQueue*>(cmq);
554}
555
556int Camera2Device::MetadataQueue::consumer_buffer_count(
557 const camera2_request_queue_src_ops_t *q)
558{
559 MetadataQueue *queue = getInstance(q);
560 return queue->getBufferCount();
561}
562
563int Camera2Device::MetadataQueue::consumer_dequeue(
564 const camera2_request_queue_src_ops_t *q,
565 camera_metadata_t **buffer)
566{
567 MetadataQueue *queue = getInstance(q);
568 return queue->dequeue(buffer, true);
569}
570
571int Camera2Device::MetadataQueue::consumer_free(
572 const camera2_request_queue_src_ops_t *q,
573 camera_metadata_t *old_buffer)
574{
575 MetadataQueue *queue = getInstance(q);
576 free_camera_metadata(old_buffer);
577 return OK;
578}
579
580int Camera2Device::MetadataQueue::producer_dequeue(
581 const camera2_frame_queue_dst_ops_t *q,
582 size_t entries, size_t bytes,
583 camera_metadata_t **buffer)
584{
585 camera_metadata_t *new_buffer =
586 allocate_camera_metadata(entries, bytes);
587 if (new_buffer == NULL) return NO_MEMORY;
588 *buffer = new_buffer;
589 return OK;
590}
591
592int Camera2Device::MetadataQueue::producer_cancel(
593 const camera2_frame_queue_dst_ops_t *q,
594 camera_metadata_t *old_buffer)
595{
596 free_camera_metadata(old_buffer);
597 return OK;
598}
599
600int Camera2Device::MetadataQueue::producer_enqueue(
601 const camera2_frame_queue_dst_ops_t *q,
602 camera_metadata_t *filled_buffer)
603{
604 MetadataQueue *queue = getInstance(q);
605 return queue->enqueue(filled_buffer);
606}
607
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700608/**
609 * Camera2Device::StreamAdapter
610 */
611
612#ifndef container_of
613#define container_of(ptr, type, member) \
614 (type *)((char*)(ptr) - offsetof(type, member))
615#endif
616
617Camera2Device::StreamAdapter::StreamAdapter(camera2_device_t *d):
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700618 mState(RELEASED),
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700619 mDevice(d),
620 mId(-1),
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700621 mWidth(0), mHeight(0), mFormat(0), mSize(0), mUsage(0),
622 mMaxProducerBuffers(0), mMaxConsumerBuffers(0),
623 mTotalBuffers(0),
624 mFormatRequested(0),
625 mActiveBuffers(0),
626 mFrameCount(0),
627 mLastTimestamp(0)
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700628{
629 camera2_stream_ops::dequeue_buffer = dequeue_buffer;
630 camera2_stream_ops::enqueue_buffer = enqueue_buffer;
631 camera2_stream_ops::cancel_buffer = cancel_buffer;
632 camera2_stream_ops::set_crop = set_crop;
633}
634
635Camera2Device::StreamAdapter::~StreamAdapter() {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700636 if (mState != RELEASED) {
637 release();
638 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700639}
640
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700641status_t Camera2Device::StreamAdapter::connectToDevice(
642 sp<ANativeWindow> consumer,
643 uint32_t width, uint32_t height, int format, size_t size) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700644 status_t res;
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700645 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700646
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700647 if (mState != RELEASED) return INVALID_OPERATION;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700648 if (consumer == NULL) {
649 ALOGE("%s: Null consumer passed to stream adapter", __FUNCTION__);
650 return BAD_VALUE;
651 }
652
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700653 ALOGV("%s: New stream parameters %d x %d, format 0x%x, size %d",
654 __FUNCTION__, width, height, format, size);
655
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700656 mConsumerInterface = consumer;
657 mWidth = width;
658 mHeight = height;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700659 mSize = (format == HAL_PIXEL_FORMAT_BLOB) ? size : 0;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700660 mFormatRequested = format;
661
662 // Allocate device-side stream interface
663
664 uint32_t id;
665 uint32_t formatActual;
666 uint32_t usage;
667 uint32_t maxBuffers = 2;
668 res = mDevice->ops->allocate_stream(mDevice,
669 mWidth, mHeight, mFormatRequested, getStreamOps(),
670 &id, &formatActual, &usage, &maxBuffers);
671 if (res != OK) {
672 ALOGE("%s: Device stream allocation failed: %s (%d)",
673 __FUNCTION__, strerror(-res), res);
674 return res;
675 }
676
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700677 ALOGV("%s: Allocated stream id %d, actual format 0x%x, "
678 "usage 0x%x, producer wants %d buffers", __FUNCTION__,
679 id, formatActual, usage, maxBuffers);
680
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700681 mId = id;
682 mFormat = formatActual;
683 mUsage = usage;
684 mMaxProducerBuffers = maxBuffers;
685
686 mState = ALLOCATED;
687
688 // Configure consumer-side ANativeWindow interface
689 res = native_window_api_connect(mConsumerInterface.get(),
690 NATIVE_WINDOW_API_CAMERA);
691 if (res != OK) {
692 ALOGE("%s: Unable to connect to native window for stream %d",
693 __FUNCTION__, mId);
694
695 return res;
696 }
697
698 mState = CONNECTED;
699
700 res = native_window_set_usage(mConsumerInterface.get(), mUsage);
701 if (res != OK) {
702 ALOGE("%s: Unable to configure usage %08x for stream %d",
703 __FUNCTION__, mUsage, mId);
704 return res;
705 }
706
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -0700707 res = native_window_set_scaling_mode(mConsumerInterface.get(),
708 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
709 if (res != OK) {
710 ALOGE("%s: Unable to configure stream scaling: %s (%d)",
711 __FUNCTION__, strerror(-res), res);
712 return res;
713 }
714
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -0700715 res = setTransform(0);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -0700716 if (res != OK) {
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -0700717 return res;
718 }
719
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700720 if (mFormat == HAL_PIXEL_FORMAT_BLOB) {
721 res = native_window_set_buffers_geometry(mConsumerInterface.get(),
722 mSize, 1, mFormat);
723 if (res != OK) {
724 ALOGE("%s: Unable to configure compressed stream buffer geometry"
725 " %d x %d, size %d for stream %d",
726 __FUNCTION__, mWidth, mHeight, mSize, mId);
727 return res;
728 }
729 } else {
730 res = native_window_set_buffers_geometry(mConsumerInterface.get(),
731 mWidth, mHeight, mFormat);
732 if (res != OK) {
733 ALOGE("%s: Unable to configure stream buffer geometry"
734 " %d x %d, format 0x%x for stream %d",
735 __FUNCTION__, mWidth, mHeight, mFormat, mId);
736 return res;
737 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700738 }
739
740 int maxConsumerBuffers;
741 res = mConsumerInterface->query(mConsumerInterface.get(),
742 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &maxConsumerBuffers);
743 if (res != OK) {
744 ALOGE("%s: Unable to query consumer undequeued"
745 " buffer count for stream %d", __FUNCTION__, mId);
746 return res;
747 }
748 mMaxConsumerBuffers = maxConsumerBuffers;
749
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700750 ALOGV("%s: Consumer wants %d buffers", __FUNCTION__,
751 mMaxConsumerBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700752
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700753 mTotalBuffers = mMaxConsumerBuffers + mMaxProducerBuffers;
754 mActiveBuffers = 0;
755 mFrameCount = 0;
756 mLastTimestamp = 0;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700757
758 res = native_window_set_buffer_count(mConsumerInterface.get(),
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700759 mTotalBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700760 if (res != OK) {
761 ALOGE("%s: Unable to set buffer count for stream %d",
762 __FUNCTION__, mId);
763 return res;
764 }
765
766 // Register allocated buffers with HAL device
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700767 buffer_handle_t *buffers = new buffer_handle_t[mTotalBuffers];
768 ANativeWindowBuffer **anwBuffers = new ANativeWindowBuffer*[mTotalBuffers];
769 uint32_t bufferIdx = 0;
770 for (; bufferIdx < mTotalBuffers; bufferIdx++) {
Jamie Gennis1e5b2b32012-06-13 16:29:51 -0700771 res = native_window_dequeue_buffer_and_wait(mConsumerInterface.get(),
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700772 &anwBuffers[bufferIdx]);
773 if (res != OK) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700774 ALOGE("%s: Unable to dequeue buffer %d for initial registration for "
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700775 "stream %d", __FUNCTION__, bufferIdx, mId);
776 goto cleanUpBuffers;
777 }
778
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700779 buffers[bufferIdx] = anwBuffers[bufferIdx]->handle;
780 }
781
782 res = mDevice->ops->register_stream_buffers(mDevice,
783 mId,
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700784 mTotalBuffers,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700785 buffers);
786 if (res != OK) {
787 ALOGE("%s: Unable to register buffers with HAL device for stream %d",
788 __FUNCTION__, mId);
789 } else {
790 mState = ACTIVE;
791 }
792
793cleanUpBuffers:
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700794 for (uint32_t i = 0; i < bufferIdx; i++) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700795 res = mConsumerInterface->cancelBuffer(mConsumerInterface.get(),
Jamie Gennis1e5b2b32012-06-13 16:29:51 -0700796 anwBuffers[i], -1);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700797 if (res != OK) {
798 ALOGE("%s: Unable to cancel buffer %d after registration",
799 __FUNCTION__, i);
800 }
801 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700802 delete[] anwBuffers;
803 delete[] buffers;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700804
805 return res;
806}
807
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700808status_t Camera2Device::StreamAdapter::release() {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700809 status_t res;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700810 ALOGV("%s: Releasing stream %d", __FUNCTION__, mId);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700811 if (mState >= ALLOCATED) {
812 res = mDevice->ops->release_stream(mDevice, mId);
813 if (res != OK) {
814 ALOGE("%s: Unable to release stream %d",
815 __FUNCTION__, mId);
816 return res;
817 }
818 }
819 if (mState >= CONNECTED) {
820 res = native_window_api_disconnect(mConsumerInterface.get(),
821 NATIVE_WINDOW_API_CAMERA);
822 if (res != OK) {
823 ALOGE("%s: Unable to disconnect stream %d from native window",
824 __FUNCTION__, mId);
825 return res;
826 }
827 }
828 mId = -1;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700829 mState = RELEASED;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700830 return OK;
831}
832
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -0700833status_t Camera2Device::StreamAdapter::setTransform(int transform) {
834 status_t res;
835 if (mState < CONNECTED) {
836 ALOGE("%s: Cannot set transform on unconnected stream", __FUNCTION__);
837 return INVALID_OPERATION;
838 }
839 res = native_window_set_buffers_transform(mConsumerInterface.get(),
840 transform);
841 if (res != OK) {
842 ALOGE("%s: Unable to configure stream transform to %x: %s (%d)",
843 __FUNCTION__, transform, strerror(-res), res);
844 }
845 return res;
846}
847
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700848status_t Camera2Device::StreamAdapter::dump(int fd,
849 const Vector<String16>& args) {
850 String8 result = String8::format(" Stream %d: %d x %d, format 0x%x\n",
851 mId, mWidth, mHeight, mFormat);
852 result.appendFormat(" size %d, usage 0x%x, requested format 0x%x\n",
853 mSize, mUsage, mFormatRequested);
854 result.appendFormat(" total buffers: %d, dequeued buffers: %d\n",
855 mTotalBuffers, mActiveBuffers);
856 result.appendFormat(" frame count: %d, last timestamp %lld\n",
857 mFrameCount, mLastTimestamp);
858 write(fd, result.string(), result.size());
859 return OK;
860}
861
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700862const camera2_stream_ops *Camera2Device::StreamAdapter::getStreamOps() {
863 return static_cast<camera2_stream_ops *>(this);
864}
865
866ANativeWindow* Camera2Device::StreamAdapter::toANW(
867 const camera2_stream_ops_t *w) {
868 return static_cast<const StreamAdapter*>(w)->mConsumerInterface.get();
869}
870
871int Camera2Device::StreamAdapter::dequeue_buffer(const camera2_stream_ops_t *w,
872 buffer_handle_t** buffer) {
873 int res;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700874 StreamAdapter* stream =
875 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
876 if (stream->mState != ACTIVE) {
877 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700878 return INVALID_OPERATION;
879 }
880
881 ANativeWindow *a = toANW(w);
882 ANativeWindowBuffer* anb;
Jamie Gennis1e5b2b32012-06-13 16:29:51 -0700883 res = native_window_dequeue_buffer_and_wait(a, &anb);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700884 if (res != OK) return res;
885
886 *buffer = &(anb->handle);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700887 stream->mActiveBuffers++;
888
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700889 ALOGVV("%s: Buffer %p", __FUNCTION__, *buffer);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700890 return res;
891}
892
893int Camera2Device::StreamAdapter::enqueue_buffer(const camera2_stream_ops_t* w,
894 int64_t timestamp,
895 buffer_handle_t* buffer) {
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700896 StreamAdapter *stream =
897 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700898 ALOGVV("%s: Stream %d: Buffer %p captured at %lld ns",
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -0700899 __FUNCTION__, stream->mId, buffer, timestamp);
900 int state = stream->mState;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700901 if (state != ACTIVE) {
902 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
903 return INVALID_OPERATION;
904 }
905 ANativeWindow *a = toANW(w);
906 status_t err;
907 err = native_window_set_buffers_timestamp(a, timestamp);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -0700908 if (err != OK) {
909 ALOGE("%s: Error setting timestamp on native window: %s (%d)",
910 __FUNCTION__, strerror(-err), err);
911 return err;
912 }
913 err = a->queueBuffer(a,
Jamie Gennis1e5b2b32012-06-13 16:29:51 -0700914 container_of(buffer, ANativeWindowBuffer, handle), -1);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -0700915 if (err != OK) {
916 ALOGE("%s: Error queueing buffer to native window: %s (%d)",
917 __FUNCTION__, strerror(-err), err);
918 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700919 stream->mActiveBuffers--;
920 stream->mFrameCount++;
921 stream->mLastTimestamp = timestamp;
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -0700922 return err;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700923}
924
925int Camera2Device::StreamAdapter::cancel_buffer(const camera2_stream_ops_t* w,
926 buffer_handle_t* buffer) {
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700927 StreamAdapter *stream =
928 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
929 if (stream->mState != ACTIVE) {
930 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700931 return INVALID_OPERATION;
932 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700933 stream->mActiveBuffers--;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700934 ANativeWindow *a = toANW(w);
935 return a->cancelBuffer(a,
Jamie Gennis1e5b2b32012-06-13 16:29:51 -0700936 container_of(buffer, ANativeWindowBuffer, handle), -1);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700937}
938
939int Camera2Device::StreamAdapter::set_crop(const camera2_stream_ops_t* w,
940 int left, int top, int right, int bottom) {
941 int state = static_cast<const StreamAdapter*>(w)->mState;
942 if (state != ACTIVE) {
943 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
944 return INVALID_OPERATION;
945 }
946 ANativeWindow *a = toANW(w);
947 android_native_rect_t crop = { left, top, right, bottom };
948 return native_window_set_crop(a, &crop);
949}
950
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700951
952}; // namespace android