blob: 7c97e1e2f422e01783b9ad925b5fd622d183138c [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 Talvala160d4af2012-08-03 09:40:16 -0700112 setNotifyCallback(NULL);
113
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700114 return OK;
115}
116
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700117status_t Camera2Device::dump(int fd, const Vector<String16>& args) {
118
119 String8 result;
Eino-Ville Talvala97197152012-08-06 14:25:19 -0700120 int detailLevel = 0;
121 int n = args.size();
122 String16 detailOption("-d");
123 for (int i = 0; i + 1 < n; i++) {
124 if (args[i] == detailOption) {
125 String8 levelStr(args[i+1]);
126 detailLevel = atoi(levelStr.string());
127 }
128 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700129
Eino-Ville Talvala603b12e2012-08-08 09:25:58 -0700130 result.appendFormat(" Camera2Device[%d] dump (detail level %d):\n",
131 mId, detailLevel);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700132
Eino-Ville Talvala97197152012-08-06 14:25:19 -0700133 if (detailLevel > 0) {
134 result = " Request queue contents:\n";
135 write(fd, result.string(), result.size());
136 mRequestQueue.dump(fd, args);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700137
Eino-Ville Talvala97197152012-08-06 14:25:19 -0700138 result = " Frame queue contents:\n";
139 write(fd, result.string(), result.size());
140 mFrameQueue.dump(fd, args);
141 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700142
143 result = " Active streams:\n";
144 write(fd, result.string(), result.size());
145 for (StreamList::iterator s = mStreams.begin(); s != mStreams.end(); s++) {
146 (*s)->dump(fd, args);
147 }
148
149 result = " HAL device dump:\n";
150 write(fd, result.string(), result.size());
151
152 status_t res;
153 res = mDevice->ops->dump(mDevice, fd);
154
155 return res;
156}
157
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700158camera_metadata_t *Camera2Device::info() {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700159 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700160
161 return mDeviceInfo;
162}
163
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700164status_t Camera2Device::capture(camera_metadata_t* request) {
165 ALOGV("%s: E", __FUNCTION__);
166
167 mRequestQueue.enqueue(request);
168 return OK;
169}
170
171
172status_t Camera2Device::setStreamingRequest(camera_metadata_t* request) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700173 ALOGV("%s: E", __FUNCTION__);
174
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700175 mRequestQueue.setStreamSlot(request);
176 return OK;
177}
178
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700179status_t Camera2Device::createStream(sp<ANativeWindow> consumer,
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700180 uint32_t width, uint32_t height, int format, size_t size, int *id) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700181 status_t res;
182 ALOGV("%s: E", __FUNCTION__);
183
184 sp<StreamAdapter> stream = new StreamAdapter(mDevice);
185
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700186 res = stream->connectToDevice(consumer, width, height, format, size);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700187 if (res != OK) {
188 ALOGE("%s: Camera %d: Unable to create stream (%d x %d, format %x):"
189 "%s (%d)",
190 __FUNCTION__, mId, width, height, format, strerror(-res), res);
191 return res;
192 }
193
194 *id = stream->getId();
195
196 mStreams.push_back(stream);
197 return OK;
198}
199
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700200status_t Camera2Device::getStreamInfo(int id,
201 uint32_t *width, uint32_t *height, uint32_t *format) {
202 ALOGV("%s: E", __FUNCTION__);
203 bool found = false;
204 StreamList::iterator streamI;
205 for (streamI = mStreams.begin();
206 streamI != mStreams.end(); streamI++) {
207 if ((*streamI)->getId() == id) {
208 found = true;
209 break;
210 }
211 }
212 if (!found) {
213 ALOGE("%s: Camera %d: Stream %d does not exist",
214 __FUNCTION__, mId, id);
215 return BAD_VALUE;
216 }
217
218 if (width) *width = (*streamI)->getWidth();
219 if (height) *height = (*streamI)->getHeight();
220 if (format) *format = (*streamI)->getFormat();
221
222 return OK;
223}
224
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -0700225status_t Camera2Device::setStreamTransform(int id,
226 int transform) {
227 ALOGV("%s: E", __FUNCTION__);
228 bool found = false;
229 StreamList::iterator streamI;
230 for (streamI = mStreams.begin();
231 streamI != mStreams.end(); streamI++) {
232 if ((*streamI)->getId() == id) {
233 found = true;
234 break;
235 }
236 }
237 if (!found) {
238 ALOGE("%s: Camera %d: Stream %d does not exist",
239 __FUNCTION__, mId, id);
240 return BAD_VALUE;
241 }
242
243 return (*streamI)->setTransform(transform);
244}
245
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700246status_t Camera2Device::deleteStream(int id) {
247 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700248 bool found = false;
249 for (StreamList::iterator streamI = mStreams.begin();
250 streamI != mStreams.end(); streamI++) {
251 if ((*streamI)->getId() == id) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700252 status_t res = (*streamI)->release();
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700253 if (res != OK) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700254 ALOGE("%s: Unable to release stream %d from HAL device: "
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700255 "%s (%d)", __FUNCTION__, id, strerror(-res), res);
256 return res;
257 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700258 mStreams.erase(streamI);
259 found = true;
260 break;
261 }
262 }
263 if (!found) {
264 ALOGE("%s: Camera %d: Unable to find stream %d to delete",
265 __FUNCTION__, mId, id);
266 return BAD_VALUE;
267 }
268 return OK;
269}
270
271status_t Camera2Device::createDefaultRequest(int templateId,
272 camera_metadata_t **request) {
273 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700274 return mDevice->ops->construct_default_request(
275 mDevice, templateId, request);
276}
277
278status_t Camera2Device::waitUntilDrained() {
279 static const uint32_t kSleepTime = 50000; // 50 ms
280 static const uint32_t kMaxSleepTime = 10000000; // 10 s
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700281 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700282 if (mRequestQueue.getBufferCount() ==
283 CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS) return INVALID_OPERATION;
284
285 // TODO: Set up notifications from HAL, instead of sleeping here
286 uint32_t totalTime = 0;
287 while (mDevice->ops->get_in_progress_count(mDevice) > 0) {
288 usleep(kSleepTime);
289 totalTime += kSleepTime;
290 if (totalTime > kMaxSleepTime) {
291 ALOGE("%s: Waited %d us, requests still in flight", __FUNCTION__,
292 totalTime);
293 return TIMED_OUT;
294 }
295 }
296 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700297}
298
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700299status_t Camera2Device::setNotifyCallback(NotificationListener *listener) {
300 status_t res;
301 res = mDevice->ops->set_notify_callback(mDevice, notificationCallback,
302 reinterpret_cast<void*>(listener) );
303 if (res != OK) {
304 ALOGE("%s: Unable to set notification callback!", __FUNCTION__);
305 }
306 return res;
307}
308
309void Camera2Device::notificationCallback(int32_t msg_type,
310 int32_t ext1,
311 int32_t ext2,
312 int32_t ext3,
313 void *user) {
314 NotificationListener *listener = reinterpret_cast<NotificationListener*>(user);
315 ALOGV("%s: Notification %d, arguments %d, %d, %d", __FUNCTION__, msg_type,
316 ext1, ext2, ext3);
317 if (listener != NULL) {
318 switch (msg_type) {
319 case CAMERA2_MSG_ERROR:
320 listener->notifyError(ext1, ext2, ext3);
321 break;
322 case CAMERA2_MSG_SHUTTER: {
323 nsecs_t timestamp = (nsecs_t)ext2 | ((nsecs_t)(ext3) << 32 );
324 listener->notifyShutter(ext1, timestamp);
325 break;
326 }
327 case CAMERA2_MSG_AUTOFOCUS:
328 listener->notifyAutoFocus(ext1, ext2);
329 break;
330 case CAMERA2_MSG_AUTOEXPOSURE:
331 listener->notifyAutoExposure(ext1, ext2);
332 break;
333 case CAMERA2_MSG_AUTOWB:
334 listener->notifyAutoWhitebalance(ext1, ext2);
335 break;
336 default:
337 ALOGE("%s: Unknown notification %d (arguments %d, %d, %d)!",
338 __FUNCTION__, msg_type, ext1, ext2, ext3);
339 }
340 }
341}
342
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700343status_t Camera2Device::triggerAutofocus(uint32_t id) {
344 status_t res;
345 ALOGV("%s: Triggering autofocus, id %d", __FUNCTION__, id);
346 res = mDevice->ops->trigger_action(mDevice,
347 CAMERA2_TRIGGER_AUTOFOCUS, id, 0);
348 if (res != OK) {
349 ALOGE("%s: Error triggering autofocus (id %d)",
350 __FUNCTION__, id);
351 }
352 return res;
353}
354
355status_t Camera2Device::triggerCancelAutofocus(uint32_t id) {
356 status_t res;
357 ALOGV("%s: Canceling autofocus, id %d", __FUNCTION__, id);
358 res = mDevice->ops->trigger_action(mDevice,
359 CAMERA2_TRIGGER_CANCEL_AUTOFOCUS, id, 0);
360 if (res != OK) {
361 ALOGE("%s: Error canceling autofocus (id %d)",
362 __FUNCTION__, id);
363 }
364 return res;
365}
366
367status_t Camera2Device::triggerPrecaptureMetering(uint32_t id) {
368 status_t res;
369 ALOGV("%s: Triggering precapture metering, id %d", __FUNCTION__, id);
370 res = mDevice->ops->trigger_action(mDevice,
371 CAMERA2_TRIGGER_PRECAPTURE_METERING, id, 0);
372 if (res != OK) {
373 ALOGE("%s: Error triggering precapture metering (id %d)",
374 __FUNCTION__, id);
375 }
376 return res;
377}
378
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700379/**
380 * Camera2Device::NotificationListener
381 */
382
383Camera2Device::NotificationListener::~NotificationListener() {
384}
385
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700386/**
387 * Camera2Device::MetadataQueue
388 */
389
390Camera2Device::MetadataQueue::MetadataQueue():
391 mDevice(NULL),
392 mFrameCount(0),
393 mCount(0),
394 mStreamSlotCount(0),
395 mSignalConsumer(true)
396{
397 camera2_request_queue_src_ops::dequeue_request = consumer_dequeue;
398 camera2_request_queue_src_ops::request_count = consumer_buffer_count;
399 camera2_request_queue_src_ops::free_request = consumer_free;
400
401 camera2_frame_queue_dst_ops::dequeue_frame = producer_dequeue;
402 camera2_frame_queue_dst_ops::cancel_frame = producer_cancel;
403 camera2_frame_queue_dst_ops::enqueue_frame = producer_enqueue;
404}
405
406Camera2Device::MetadataQueue::~MetadataQueue() {
407 Mutex::Autolock l(mMutex);
408 freeBuffers(mEntries.begin(), mEntries.end());
409 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
410}
411
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700412// Connect to camera2 HAL as consumer (input requests/reprocessing)
413status_t Camera2Device::MetadataQueue::setConsumerDevice(camera2_device_t *d) {
414 status_t res;
415 res = d->ops->set_request_queue_src_ops(d,
416 this);
417 if (res != OK) return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700418 mDevice = d;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700419 return OK;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700420}
421
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700422status_t Camera2Device::MetadataQueue::setProducerDevice(camera2_device_t *d) {
423 status_t res;
424 res = d->ops->set_frame_queue_dst_ops(d,
425 this);
426 return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700427}
428
429// Real interfaces
430status_t Camera2Device::MetadataQueue::enqueue(camera_metadata_t *buf) {
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700431 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700432 Mutex::Autolock l(mMutex);
433
434 mCount++;
435 mEntries.push_back(buf);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700436
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700437 return signalConsumerLocked();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700438}
439
440int Camera2Device::MetadataQueue::getBufferCount() {
441 Mutex::Autolock l(mMutex);
442 if (mStreamSlotCount > 0) {
443 return CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS;
444 }
445 return mCount;
446}
447
448status_t Camera2Device::MetadataQueue::dequeue(camera_metadata_t **buf,
449 bool incrementCount)
450{
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700451 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700452 status_t res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700453 Mutex::Autolock l(mMutex);
454
455 if (mCount == 0) {
456 if (mStreamSlotCount == 0) {
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700457 ALOGVV("%s: Empty", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700458 *buf = NULL;
459 mSignalConsumer = true;
460 return OK;
461 }
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700462 ALOGVV("%s: Streaming %d frames to queue", __FUNCTION__,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700463 mStreamSlotCount);
464
465 for (List<camera_metadata_t*>::iterator slotEntry = mStreamSlot.begin();
466 slotEntry != mStreamSlot.end();
467 slotEntry++ ) {
468 size_t entries = get_camera_metadata_entry_count(*slotEntry);
469 size_t dataBytes = get_camera_metadata_data_count(*slotEntry);
470
471 camera_metadata_t *copy =
472 allocate_camera_metadata(entries, dataBytes);
473 append_camera_metadata(copy, *slotEntry);
474 mEntries.push_back(copy);
475 }
476 mCount = mStreamSlotCount;
477 }
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700478 ALOGVV("MetadataQueue: deque (%d buffers)", mCount);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700479 camera_metadata_t *b = *(mEntries.begin());
480 mEntries.erase(mEntries.begin());
481
482 if (incrementCount) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700483 camera_metadata_entry_t frameCount;
484 res = find_camera_metadata_entry(b,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700485 ANDROID_REQUEST_FRAME_COUNT,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700486 &frameCount);
487 if (res != OK) {
488 ALOGE("%s: Unable to add frame count: %s (%d)",
489 __FUNCTION__, strerror(-res), res);
490 } else {
491 *frameCount.data.i32 = mFrameCount;
492 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700493 mFrameCount++;
494 }
495
496 *buf = b;
497 mCount--;
498
499 return OK;
500}
501
502status_t Camera2Device::MetadataQueue::waitForBuffer(nsecs_t timeout)
503{
504 Mutex::Autolock l(mMutex);
505 status_t res;
506 while (mCount == 0) {
507 res = notEmpty.waitRelative(mMutex,timeout);
508 if (res != OK) return res;
509 }
510 return OK;
511}
512
513status_t Camera2Device::MetadataQueue::setStreamSlot(camera_metadata_t *buf)
514{
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700515 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700516 Mutex::Autolock l(mMutex);
517 if (buf == NULL) {
518 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
519 mStreamSlotCount = 0;
520 return OK;
521 }
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700522 camera_metadata_t *buf2 = clone_camera_metadata(buf);
523 if (!buf2) {
524 ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__);
525 return NO_MEMORY;
526 }
527
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700528 if (mStreamSlotCount > 1) {
529 List<camera_metadata_t*>::iterator deleter = ++mStreamSlot.begin();
530 freeBuffers(++mStreamSlot.begin(), mStreamSlot.end());
531 mStreamSlotCount = 1;
532 }
533 if (mStreamSlotCount == 1) {
534 free_camera_metadata( *(mStreamSlot.begin()) );
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700535 *(mStreamSlot.begin()) = buf2;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700536 } else {
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700537 mStreamSlot.push_front(buf2);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700538 mStreamSlotCount = 1;
539 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700540 return signalConsumerLocked();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700541}
542
543status_t Camera2Device::MetadataQueue::setStreamSlot(
544 const List<camera_metadata_t*> &bufs)
545{
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700546 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700547 Mutex::Autolock l(mMutex);
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700548 status_t res;
549
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700550 if (mStreamSlotCount > 0) {
551 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
552 }
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700553 mStreamSlotCount = 0;
554 for (List<camera_metadata_t*>::const_iterator r = bufs.begin();
555 r != bufs.end(); r++) {
556 camera_metadata_t *r2 = clone_camera_metadata(*r);
557 if (!r2) {
558 ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__);
559 return NO_MEMORY;
560 }
561 mStreamSlot.push_back(r2);
562 mStreamSlotCount++;
563 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700564 return signalConsumerLocked();
565}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700566
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700567status_t Camera2Device::MetadataQueue::dump(int fd,
568 const Vector<String16>& args) {
569 String8 result;
570 status_t notLocked;
571 notLocked = mMutex.tryLock();
572 if (notLocked) {
573 result.append(" (Unable to lock queue mutex)\n");
574 }
575 result.appendFormat(" Current frame number: %d\n", mFrameCount);
576 if (mStreamSlotCount == 0) {
577 result.append(" Stream slot: Empty\n");
578 write(fd, result.string(), result.size());
579 } else {
580 result.appendFormat(" Stream slot: %d entries\n",
581 mStreamSlot.size());
582 int i = 0;
583 for (List<camera_metadata_t*>::iterator r = mStreamSlot.begin();
584 r != mStreamSlot.end(); r++) {
585 result = String8::format(" Stream slot buffer %d:\n", i);
586 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700587 dump_indented_camera_metadata(*r, fd, 2, 10);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700588 i++;
589 }
590 }
591 if (mEntries.size() == 0) {
592 result = " Main queue is empty\n";
593 write(fd, result.string(), result.size());
594 } else {
595 result = String8::format(" Main queue has %d entries:\n",
596 mEntries.size());
597 int i = 0;
598 for (List<camera_metadata_t*>::iterator r = mEntries.begin();
599 r != mEntries.end(); r++) {
600 result = String8::format(" Queue entry %d:\n", i);
601 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700602 dump_indented_camera_metadata(*r, fd, 2, 10);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700603 i++;
604 }
605 }
606
607 if (notLocked == 0) {
608 mMutex.unlock();
609 }
610
611 return OK;
612}
613
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700614status_t Camera2Device::MetadataQueue::signalConsumerLocked() {
615 status_t res = OK;
616 notEmpty.signal();
617 if (mSignalConsumer && mDevice != NULL) {
618 mSignalConsumer = false;
619
620 mMutex.unlock();
621 ALOGV("%s: Signaling consumer", __FUNCTION__);
622 res = mDevice->ops->notify_request_queue_not_empty(mDevice);
623 mMutex.lock();
624 }
625 return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700626}
627
628status_t Camera2Device::MetadataQueue::freeBuffers(
629 List<camera_metadata_t*>::iterator start,
630 List<camera_metadata_t*>::iterator end)
631{
632 while (start != end) {
633 free_camera_metadata(*start);
634 start = mStreamSlot.erase(start);
635 }
636 return OK;
637}
638
639Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
640 const camera2_request_queue_src_ops_t *q)
641{
642 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
643 return const_cast<MetadataQueue*>(cmq);
644}
645
646Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
647 const camera2_frame_queue_dst_ops_t *q)
648{
649 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
650 return const_cast<MetadataQueue*>(cmq);
651}
652
653int Camera2Device::MetadataQueue::consumer_buffer_count(
654 const camera2_request_queue_src_ops_t *q)
655{
656 MetadataQueue *queue = getInstance(q);
657 return queue->getBufferCount();
658}
659
660int Camera2Device::MetadataQueue::consumer_dequeue(
661 const camera2_request_queue_src_ops_t *q,
662 camera_metadata_t **buffer)
663{
664 MetadataQueue *queue = getInstance(q);
665 return queue->dequeue(buffer, true);
666}
667
668int Camera2Device::MetadataQueue::consumer_free(
669 const camera2_request_queue_src_ops_t *q,
670 camera_metadata_t *old_buffer)
671{
672 MetadataQueue *queue = getInstance(q);
673 free_camera_metadata(old_buffer);
674 return OK;
675}
676
677int Camera2Device::MetadataQueue::producer_dequeue(
678 const camera2_frame_queue_dst_ops_t *q,
679 size_t entries, size_t bytes,
680 camera_metadata_t **buffer)
681{
682 camera_metadata_t *new_buffer =
683 allocate_camera_metadata(entries, bytes);
684 if (new_buffer == NULL) return NO_MEMORY;
685 *buffer = new_buffer;
686 return OK;
687}
688
689int Camera2Device::MetadataQueue::producer_cancel(
690 const camera2_frame_queue_dst_ops_t *q,
691 camera_metadata_t *old_buffer)
692{
693 free_camera_metadata(old_buffer);
694 return OK;
695}
696
697int Camera2Device::MetadataQueue::producer_enqueue(
698 const camera2_frame_queue_dst_ops_t *q,
699 camera_metadata_t *filled_buffer)
700{
701 MetadataQueue *queue = getInstance(q);
702 return queue->enqueue(filled_buffer);
703}
704
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700705/**
706 * Camera2Device::StreamAdapter
707 */
708
709#ifndef container_of
710#define container_of(ptr, type, member) \
711 (type *)((char*)(ptr) - offsetof(type, member))
712#endif
713
714Camera2Device::StreamAdapter::StreamAdapter(camera2_device_t *d):
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700715 mState(RELEASED),
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700716 mDevice(d),
717 mId(-1),
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700718 mWidth(0), mHeight(0), mFormat(0), mSize(0), mUsage(0),
719 mMaxProducerBuffers(0), mMaxConsumerBuffers(0),
720 mTotalBuffers(0),
721 mFormatRequested(0),
722 mActiveBuffers(0),
723 mFrameCount(0),
724 mLastTimestamp(0)
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700725{
726 camera2_stream_ops::dequeue_buffer = dequeue_buffer;
727 camera2_stream_ops::enqueue_buffer = enqueue_buffer;
728 camera2_stream_ops::cancel_buffer = cancel_buffer;
729 camera2_stream_ops::set_crop = set_crop;
730}
731
732Camera2Device::StreamAdapter::~StreamAdapter() {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700733 if (mState != RELEASED) {
734 release();
735 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700736}
737
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700738status_t Camera2Device::StreamAdapter::connectToDevice(
739 sp<ANativeWindow> consumer,
740 uint32_t width, uint32_t height, int format, size_t size) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700741 status_t res;
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700742 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700743
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700744 if (mState != RELEASED) return INVALID_OPERATION;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700745 if (consumer == NULL) {
746 ALOGE("%s: Null consumer passed to stream adapter", __FUNCTION__);
747 return BAD_VALUE;
748 }
749
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700750 ALOGV("%s: New stream parameters %d x %d, format 0x%x, size %d",
751 __FUNCTION__, width, height, format, size);
752
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700753 mConsumerInterface = consumer;
754 mWidth = width;
755 mHeight = height;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700756 mSize = (format == HAL_PIXEL_FORMAT_BLOB) ? size : 0;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700757 mFormatRequested = format;
758
759 // Allocate device-side stream interface
760
761 uint32_t id;
762 uint32_t formatActual;
763 uint32_t usage;
764 uint32_t maxBuffers = 2;
765 res = mDevice->ops->allocate_stream(mDevice,
766 mWidth, mHeight, mFormatRequested, getStreamOps(),
767 &id, &formatActual, &usage, &maxBuffers);
768 if (res != OK) {
769 ALOGE("%s: Device stream allocation failed: %s (%d)",
770 __FUNCTION__, strerror(-res), res);
771 return res;
772 }
773
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700774 ALOGV("%s: Allocated stream id %d, actual format 0x%x, "
775 "usage 0x%x, producer wants %d buffers", __FUNCTION__,
776 id, formatActual, usage, maxBuffers);
777
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700778 mId = id;
779 mFormat = formatActual;
780 mUsage = usage;
781 mMaxProducerBuffers = maxBuffers;
782
783 mState = ALLOCATED;
784
785 // Configure consumer-side ANativeWindow interface
786 res = native_window_api_connect(mConsumerInterface.get(),
787 NATIVE_WINDOW_API_CAMERA);
788 if (res != OK) {
789 ALOGE("%s: Unable to connect to native window for stream %d",
790 __FUNCTION__, mId);
791
792 return res;
793 }
794
795 mState = CONNECTED;
796
797 res = native_window_set_usage(mConsumerInterface.get(), mUsage);
798 if (res != OK) {
799 ALOGE("%s: Unable to configure usage %08x for stream %d",
800 __FUNCTION__, mUsage, mId);
801 return res;
802 }
803
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -0700804 res = native_window_set_scaling_mode(mConsumerInterface.get(),
805 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
806 if (res != OK) {
807 ALOGE("%s: Unable to configure stream scaling: %s (%d)",
808 __FUNCTION__, strerror(-res), res);
809 return res;
810 }
811
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -0700812 res = setTransform(0);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -0700813 if (res != OK) {
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -0700814 return res;
815 }
816
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700817 if (mFormat == HAL_PIXEL_FORMAT_BLOB) {
818 res = native_window_set_buffers_geometry(mConsumerInterface.get(),
819 mSize, 1, mFormat);
820 if (res != OK) {
821 ALOGE("%s: Unable to configure compressed stream buffer geometry"
822 " %d x %d, size %d for stream %d",
823 __FUNCTION__, mWidth, mHeight, mSize, mId);
824 return res;
825 }
826 } else {
827 res = native_window_set_buffers_geometry(mConsumerInterface.get(),
828 mWidth, mHeight, mFormat);
829 if (res != OK) {
830 ALOGE("%s: Unable to configure stream buffer geometry"
831 " %d x %d, format 0x%x for stream %d",
832 __FUNCTION__, mWidth, mHeight, mFormat, mId);
833 return res;
834 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700835 }
836
837 int maxConsumerBuffers;
838 res = mConsumerInterface->query(mConsumerInterface.get(),
839 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &maxConsumerBuffers);
840 if (res != OK) {
841 ALOGE("%s: Unable to query consumer undequeued"
842 " buffer count for stream %d", __FUNCTION__, mId);
843 return res;
844 }
845 mMaxConsumerBuffers = maxConsumerBuffers;
846
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700847 ALOGV("%s: Consumer wants %d buffers", __FUNCTION__,
848 mMaxConsumerBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700849
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700850 mTotalBuffers = mMaxConsumerBuffers + mMaxProducerBuffers;
851 mActiveBuffers = 0;
852 mFrameCount = 0;
853 mLastTimestamp = 0;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700854
855 res = native_window_set_buffer_count(mConsumerInterface.get(),
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700856 mTotalBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700857 if (res != OK) {
858 ALOGE("%s: Unable to set buffer count for stream %d",
859 __FUNCTION__, mId);
860 return res;
861 }
862
863 // Register allocated buffers with HAL device
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700864 buffer_handle_t *buffers = new buffer_handle_t[mTotalBuffers];
865 ANativeWindowBuffer **anwBuffers = new ANativeWindowBuffer*[mTotalBuffers];
866 uint32_t bufferIdx = 0;
867 for (; bufferIdx < mTotalBuffers; bufferIdx++) {
Jamie Gennis1e5b2b32012-06-13 16:29:51 -0700868 res = native_window_dequeue_buffer_and_wait(mConsumerInterface.get(),
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700869 &anwBuffers[bufferIdx]);
870 if (res != OK) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700871 ALOGE("%s: Unable to dequeue buffer %d for initial registration for "
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700872 "stream %d", __FUNCTION__, bufferIdx, mId);
873 goto cleanUpBuffers;
874 }
875
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700876 buffers[bufferIdx] = anwBuffers[bufferIdx]->handle;
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -0700877 ALOGV("%s: Buffer %p allocated", __FUNCTION__, (void*)(buffers[bufferIdx]));
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700878 }
879
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -0700880 ALOGV("%s: Registering %d buffers with camera HAL", __FUNCTION__, mTotalBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700881 res = mDevice->ops->register_stream_buffers(mDevice,
882 mId,
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700883 mTotalBuffers,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700884 buffers);
885 if (res != OK) {
886 ALOGE("%s: Unable to register buffers with HAL device for stream %d",
887 __FUNCTION__, mId);
888 } else {
889 mState = ACTIVE;
890 }
891
892cleanUpBuffers:
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -0700893 ALOGV("%s: Cleaning up %d buffers", __FUNCTION__, bufferIdx);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700894 for (uint32_t i = 0; i < bufferIdx; i++) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700895 res = mConsumerInterface->cancelBuffer(mConsumerInterface.get(),
Jamie Gennis1e5b2b32012-06-13 16:29:51 -0700896 anwBuffers[i], -1);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700897 if (res != OK) {
898 ALOGE("%s: Unable to cancel buffer %d after registration",
899 __FUNCTION__, i);
900 }
901 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700902 delete[] anwBuffers;
903 delete[] buffers;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700904
905 return res;
906}
907
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700908status_t Camera2Device::StreamAdapter::release() {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700909 status_t res;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700910 ALOGV("%s: Releasing stream %d", __FUNCTION__, mId);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700911 if (mState >= ALLOCATED) {
912 res = mDevice->ops->release_stream(mDevice, mId);
913 if (res != OK) {
914 ALOGE("%s: Unable to release stream %d",
915 __FUNCTION__, mId);
916 return res;
917 }
918 }
919 if (mState >= CONNECTED) {
920 res = native_window_api_disconnect(mConsumerInterface.get(),
921 NATIVE_WINDOW_API_CAMERA);
922 if (res != OK) {
923 ALOGE("%s: Unable to disconnect stream %d from native window",
924 __FUNCTION__, mId);
925 return res;
926 }
927 }
928 mId = -1;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700929 mState = RELEASED;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700930 return OK;
931}
932
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -0700933status_t Camera2Device::StreamAdapter::setTransform(int transform) {
934 status_t res;
935 if (mState < CONNECTED) {
936 ALOGE("%s: Cannot set transform on unconnected stream", __FUNCTION__);
937 return INVALID_OPERATION;
938 }
939 res = native_window_set_buffers_transform(mConsumerInterface.get(),
940 transform);
941 if (res != OK) {
942 ALOGE("%s: Unable to configure stream transform to %x: %s (%d)",
943 __FUNCTION__, transform, strerror(-res), res);
944 }
945 return res;
946}
947
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700948status_t Camera2Device::StreamAdapter::dump(int fd,
949 const Vector<String16>& args) {
950 String8 result = String8::format(" Stream %d: %d x %d, format 0x%x\n",
951 mId, mWidth, mHeight, mFormat);
952 result.appendFormat(" size %d, usage 0x%x, requested format 0x%x\n",
953 mSize, mUsage, mFormatRequested);
954 result.appendFormat(" total buffers: %d, dequeued buffers: %d\n",
955 mTotalBuffers, mActiveBuffers);
956 result.appendFormat(" frame count: %d, last timestamp %lld\n",
957 mFrameCount, mLastTimestamp);
958 write(fd, result.string(), result.size());
959 return OK;
960}
961
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700962const camera2_stream_ops *Camera2Device::StreamAdapter::getStreamOps() {
963 return static_cast<camera2_stream_ops *>(this);
964}
965
966ANativeWindow* Camera2Device::StreamAdapter::toANW(
967 const camera2_stream_ops_t *w) {
968 return static_cast<const StreamAdapter*>(w)->mConsumerInterface.get();
969}
970
971int Camera2Device::StreamAdapter::dequeue_buffer(const camera2_stream_ops_t *w,
972 buffer_handle_t** buffer) {
973 int res;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700974 StreamAdapter* stream =
975 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
976 if (stream->mState != ACTIVE) {
977 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700978 return INVALID_OPERATION;
979 }
980
981 ANativeWindow *a = toANW(w);
982 ANativeWindowBuffer* anb;
Jamie Gennis1e5b2b32012-06-13 16:29:51 -0700983 res = native_window_dequeue_buffer_and_wait(a, &anb);
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -0700984 if (res != OK) {
985 ALOGE("Stream %d dequeue: Error from native_window: %s (%d)", stream->mId,
986 strerror(-res), res);
987 return res;
988 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700989
990 *buffer = &(anb->handle);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700991 stream->mActiveBuffers++;
992
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -0700993 ALOGVV("Stream %d dequeue: Buffer %p dequeued", stream->mId, (void*)(**buffer));
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700994 return res;
995}
996
997int Camera2Device::StreamAdapter::enqueue_buffer(const camera2_stream_ops_t* w,
998 int64_t timestamp,
999 buffer_handle_t* buffer) {
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001000 StreamAdapter *stream =
1001 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001002 ALOGVV("Stream %d enqueue: Buffer %p captured at %lld ns",
1003 stream->mId, (void*)(*buffer), timestamp);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001004 int state = stream->mState;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001005 if (state != ACTIVE) {
1006 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1007 return INVALID_OPERATION;
1008 }
1009 ANativeWindow *a = toANW(w);
1010 status_t err;
1011 err = native_window_set_buffers_timestamp(a, timestamp);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001012 if (err != OK) {
1013 ALOGE("%s: Error setting timestamp on native window: %s (%d)",
1014 __FUNCTION__, strerror(-err), err);
1015 return err;
1016 }
1017 err = a->queueBuffer(a,
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001018 container_of(buffer, ANativeWindowBuffer, handle), -1);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001019 if (err != OK) {
1020 ALOGE("%s: Error queueing buffer to native window: %s (%d)",
1021 __FUNCTION__, strerror(-err), err);
James Dong31d377b2012-08-09 17:43:46 -07001022 return err;
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001023 }
James Dong31d377b2012-08-09 17:43:46 -07001024
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001025 stream->mActiveBuffers--;
1026 stream->mFrameCount++;
1027 stream->mLastTimestamp = timestamp;
James Dong31d377b2012-08-09 17:43:46 -07001028 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001029}
1030
1031int Camera2Device::StreamAdapter::cancel_buffer(const camera2_stream_ops_t* w,
1032 buffer_handle_t* buffer) {
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001033 StreamAdapter *stream =
1034 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001035 ALOGVV("Stream %d cancel: Buffer %p",
1036 stream->mId, (void*)(*buffer));
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001037 if (stream->mState != ACTIVE) {
1038 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001039 return INVALID_OPERATION;
1040 }
James Dong31d377b2012-08-09 17:43:46 -07001041
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001042 ANativeWindow *a = toANW(w);
James Dong31d377b2012-08-09 17:43:46 -07001043 int err = a->cancelBuffer(a,
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001044 container_of(buffer, ANativeWindowBuffer, handle), -1);
James Dong31d377b2012-08-09 17:43:46 -07001045 if (err != OK) {
1046 ALOGE("%s: Error canceling buffer to native window: %s (%d)",
1047 __FUNCTION__, strerror(-err), err);
1048 return err;
1049 }
1050
1051 stream->mActiveBuffers--;
1052 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001053}
1054
1055int Camera2Device::StreamAdapter::set_crop(const camera2_stream_ops_t* w,
1056 int left, int top, int right, int bottom) {
1057 int state = static_cast<const StreamAdapter*>(w)->mState;
1058 if (state != ACTIVE) {
1059 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1060 return INVALID_OPERATION;
1061 }
1062 ANativeWindow *a = toANW(w);
1063 android_native_rect_t crop = { left, top, right, bottom };
1064 return native_window_set_crop(a, &crop);
1065}
1066
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001067
1068}; // namespace android