blob: a0096368a46a265be2c1c685ed30eb35f8186900 [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 Talvala97197152012-08-06 14:25:19 -0700130 result.appendFormat(" Camera2Device[%d] dump (detail level %d):\n", mId);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700131
Eino-Ville Talvala97197152012-08-06 14:25:19 -0700132 if (detailLevel > 0) {
133 result = " Request queue contents:\n";
134 write(fd, result.string(), result.size());
135 mRequestQueue.dump(fd, args);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700136
Eino-Ville Talvala97197152012-08-06 14:25:19 -0700137 result = " Frame queue contents:\n";
138 write(fd, result.string(), result.size());
139 mFrameQueue.dump(fd, args);
140 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700141
142 result = " Active streams:\n";
143 write(fd, result.string(), result.size());
144 for (StreamList::iterator s = mStreams.begin(); s != mStreams.end(); s++) {
145 (*s)->dump(fd, args);
146 }
147
148 result = " HAL device dump:\n";
149 write(fd, result.string(), result.size());
150
151 status_t res;
152 res = mDevice->ops->dump(mDevice, fd);
153
154 return res;
155}
156
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700157camera_metadata_t *Camera2Device::info() {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700158 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700159
160 return mDeviceInfo;
161}
162
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700163status_t Camera2Device::capture(camera_metadata_t* request) {
164 ALOGV("%s: E", __FUNCTION__);
165
166 mRequestQueue.enqueue(request);
167 return OK;
168}
169
170
171status_t Camera2Device::setStreamingRequest(camera_metadata_t* request) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700172 ALOGV("%s: E", __FUNCTION__);
173
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700174 mRequestQueue.setStreamSlot(request);
175 return OK;
176}
177
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700178status_t Camera2Device::createStream(sp<ANativeWindow> consumer,
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700179 uint32_t width, uint32_t height, int format, size_t size, int *id) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700180 status_t res;
181 ALOGV("%s: E", __FUNCTION__);
182
183 sp<StreamAdapter> stream = new StreamAdapter(mDevice);
184
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700185 res = stream->connectToDevice(consumer, width, height, format, size);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700186 if (res != OK) {
187 ALOGE("%s: Camera %d: Unable to create stream (%d x %d, format %x):"
188 "%s (%d)",
189 __FUNCTION__, mId, width, height, format, strerror(-res), res);
190 return res;
191 }
192
193 *id = stream->getId();
194
195 mStreams.push_back(stream);
196 return OK;
197}
198
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700199status_t Camera2Device::getStreamInfo(int id,
200 uint32_t *width, uint32_t *height, uint32_t *format) {
201 ALOGV("%s: E", __FUNCTION__);
202 bool found = false;
203 StreamList::iterator streamI;
204 for (streamI = mStreams.begin();
205 streamI != mStreams.end(); streamI++) {
206 if ((*streamI)->getId() == id) {
207 found = true;
208 break;
209 }
210 }
211 if (!found) {
212 ALOGE("%s: Camera %d: Stream %d does not exist",
213 __FUNCTION__, mId, id);
214 return BAD_VALUE;
215 }
216
217 if (width) *width = (*streamI)->getWidth();
218 if (height) *height = (*streamI)->getHeight();
219 if (format) *format = (*streamI)->getFormat();
220
221 return OK;
222}
223
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -0700224status_t Camera2Device::setStreamTransform(int id,
225 int transform) {
226 ALOGV("%s: E", __FUNCTION__);
227 bool found = false;
228 StreamList::iterator streamI;
229 for (streamI = mStreams.begin();
230 streamI != mStreams.end(); streamI++) {
231 if ((*streamI)->getId() == id) {
232 found = true;
233 break;
234 }
235 }
236 if (!found) {
237 ALOGE("%s: Camera %d: Stream %d does not exist",
238 __FUNCTION__, mId, id);
239 return BAD_VALUE;
240 }
241
242 return (*streamI)->setTransform(transform);
243}
244
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700245status_t Camera2Device::deleteStream(int id) {
246 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700247 bool found = false;
248 for (StreamList::iterator streamI = mStreams.begin();
249 streamI != mStreams.end(); streamI++) {
250 if ((*streamI)->getId() == id) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700251 status_t res = (*streamI)->release();
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700252 if (res != OK) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700253 ALOGE("%s: Unable to release stream %d from HAL device: "
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700254 "%s (%d)", __FUNCTION__, id, strerror(-res), res);
255 return res;
256 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700257 mStreams.erase(streamI);
258 found = true;
259 break;
260 }
261 }
262 if (!found) {
263 ALOGE("%s: Camera %d: Unable to find stream %d to delete",
264 __FUNCTION__, mId, id);
265 return BAD_VALUE;
266 }
267 return OK;
268}
269
270status_t Camera2Device::createDefaultRequest(int templateId,
271 camera_metadata_t **request) {
272 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700273 return mDevice->ops->construct_default_request(
274 mDevice, templateId, request);
275}
276
277status_t Camera2Device::waitUntilDrained() {
278 static const uint32_t kSleepTime = 50000; // 50 ms
279 static const uint32_t kMaxSleepTime = 10000000; // 10 s
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700280 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700281 if (mRequestQueue.getBufferCount() ==
282 CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS) return INVALID_OPERATION;
283
284 // TODO: Set up notifications from HAL, instead of sleeping here
285 uint32_t totalTime = 0;
286 while (mDevice->ops->get_in_progress_count(mDevice) > 0) {
287 usleep(kSleepTime);
288 totalTime += kSleepTime;
289 if (totalTime > kMaxSleepTime) {
290 ALOGE("%s: Waited %d us, requests still in flight", __FUNCTION__,
291 totalTime);
292 return TIMED_OUT;
293 }
294 }
295 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700296}
297
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700298status_t Camera2Device::setNotifyCallback(NotificationListener *listener) {
299 status_t res;
300 res = mDevice->ops->set_notify_callback(mDevice, notificationCallback,
301 reinterpret_cast<void*>(listener) );
302 if (res != OK) {
303 ALOGE("%s: Unable to set notification callback!", __FUNCTION__);
304 }
305 return res;
306}
307
308void Camera2Device::notificationCallback(int32_t msg_type,
309 int32_t ext1,
310 int32_t ext2,
311 int32_t ext3,
312 void *user) {
313 NotificationListener *listener = reinterpret_cast<NotificationListener*>(user);
314 ALOGV("%s: Notification %d, arguments %d, %d, %d", __FUNCTION__, msg_type,
315 ext1, ext2, ext3);
316 if (listener != NULL) {
317 switch (msg_type) {
318 case CAMERA2_MSG_ERROR:
319 listener->notifyError(ext1, ext2, ext3);
320 break;
321 case CAMERA2_MSG_SHUTTER: {
322 nsecs_t timestamp = (nsecs_t)ext2 | ((nsecs_t)(ext3) << 32 );
323 listener->notifyShutter(ext1, timestamp);
324 break;
325 }
326 case CAMERA2_MSG_AUTOFOCUS:
327 listener->notifyAutoFocus(ext1, ext2);
328 break;
329 case CAMERA2_MSG_AUTOEXPOSURE:
330 listener->notifyAutoExposure(ext1, ext2);
331 break;
332 case CAMERA2_MSG_AUTOWB:
333 listener->notifyAutoWhitebalance(ext1, ext2);
334 break;
335 default:
336 ALOGE("%s: Unknown notification %d (arguments %d, %d, %d)!",
337 __FUNCTION__, msg_type, ext1, ext2, ext3);
338 }
339 }
340}
341
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700342status_t Camera2Device::triggerAutofocus(uint32_t id) {
343 status_t res;
344 ALOGV("%s: Triggering autofocus, id %d", __FUNCTION__, id);
345 res = mDevice->ops->trigger_action(mDevice,
346 CAMERA2_TRIGGER_AUTOFOCUS, id, 0);
347 if (res != OK) {
348 ALOGE("%s: Error triggering autofocus (id %d)",
349 __FUNCTION__, id);
350 }
351 return res;
352}
353
354status_t Camera2Device::triggerCancelAutofocus(uint32_t id) {
355 status_t res;
356 ALOGV("%s: Canceling autofocus, id %d", __FUNCTION__, id);
357 res = mDevice->ops->trigger_action(mDevice,
358 CAMERA2_TRIGGER_CANCEL_AUTOFOCUS, id, 0);
359 if (res != OK) {
360 ALOGE("%s: Error canceling autofocus (id %d)",
361 __FUNCTION__, id);
362 }
363 return res;
364}
365
366status_t Camera2Device::triggerPrecaptureMetering(uint32_t id) {
367 status_t res;
368 ALOGV("%s: Triggering precapture metering, id %d", __FUNCTION__, id);
369 res = mDevice->ops->trigger_action(mDevice,
370 CAMERA2_TRIGGER_PRECAPTURE_METERING, id, 0);
371 if (res != OK) {
372 ALOGE("%s: Error triggering precapture metering (id %d)",
373 __FUNCTION__, id);
374 }
375 return res;
376}
377
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700378/**
379 * Camera2Device::NotificationListener
380 */
381
382Camera2Device::NotificationListener::~NotificationListener() {
383}
384
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700385/**
386 * Camera2Device::MetadataQueue
387 */
388
389Camera2Device::MetadataQueue::MetadataQueue():
390 mDevice(NULL),
391 mFrameCount(0),
392 mCount(0),
393 mStreamSlotCount(0),
394 mSignalConsumer(true)
395{
396 camera2_request_queue_src_ops::dequeue_request = consumer_dequeue;
397 camera2_request_queue_src_ops::request_count = consumer_buffer_count;
398 camera2_request_queue_src_ops::free_request = consumer_free;
399
400 camera2_frame_queue_dst_ops::dequeue_frame = producer_dequeue;
401 camera2_frame_queue_dst_ops::cancel_frame = producer_cancel;
402 camera2_frame_queue_dst_ops::enqueue_frame = producer_enqueue;
403}
404
405Camera2Device::MetadataQueue::~MetadataQueue() {
406 Mutex::Autolock l(mMutex);
407 freeBuffers(mEntries.begin(), mEntries.end());
408 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
409}
410
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700411// Connect to camera2 HAL as consumer (input requests/reprocessing)
412status_t Camera2Device::MetadataQueue::setConsumerDevice(camera2_device_t *d) {
413 status_t res;
414 res = d->ops->set_request_queue_src_ops(d,
415 this);
416 if (res != OK) return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700417 mDevice = d;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700418 return OK;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700419}
420
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700421status_t Camera2Device::MetadataQueue::setProducerDevice(camera2_device_t *d) {
422 status_t res;
423 res = d->ops->set_frame_queue_dst_ops(d,
424 this);
425 return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700426}
427
428// Real interfaces
429status_t Camera2Device::MetadataQueue::enqueue(camera_metadata_t *buf) {
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700430 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700431 Mutex::Autolock l(mMutex);
432
433 mCount++;
434 mEntries.push_back(buf);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700435
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700436 return signalConsumerLocked();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700437}
438
439int Camera2Device::MetadataQueue::getBufferCount() {
440 Mutex::Autolock l(mMutex);
441 if (mStreamSlotCount > 0) {
442 return CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS;
443 }
444 return mCount;
445}
446
447status_t Camera2Device::MetadataQueue::dequeue(camera_metadata_t **buf,
448 bool incrementCount)
449{
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700450 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700451 status_t res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700452 Mutex::Autolock l(mMutex);
453
454 if (mCount == 0) {
455 if (mStreamSlotCount == 0) {
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700456 ALOGVV("%s: Empty", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700457 *buf = NULL;
458 mSignalConsumer = true;
459 return OK;
460 }
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700461 ALOGVV("%s: Streaming %d frames to queue", __FUNCTION__,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700462 mStreamSlotCount);
463
464 for (List<camera_metadata_t*>::iterator slotEntry = mStreamSlot.begin();
465 slotEntry != mStreamSlot.end();
466 slotEntry++ ) {
467 size_t entries = get_camera_metadata_entry_count(*slotEntry);
468 size_t dataBytes = get_camera_metadata_data_count(*slotEntry);
469
470 camera_metadata_t *copy =
471 allocate_camera_metadata(entries, dataBytes);
472 append_camera_metadata(copy, *slotEntry);
473 mEntries.push_back(copy);
474 }
475 mCount = mStreamSlotCount;
476 }
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700477 ALOGVV("MetadataQueue: deque (%d buffers)", mCount);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700478 camera_metadata_t *b = *(mEntries.begin());
479 mEntries.erase(mEntries.begin());
480
481 if (incrementCount) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700482 camera_metadata_entry_t frameCount;
483 res = find_camera_metadata_entry(b,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700484 ANDROID_REQUEST_FRAME_COUNT,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700485 &frameCount);
486 if (res != OK) {
487 ALOGE("%s: Unable to add frame count: %s (%d)",
488 __FUNCTION__, strerror(-res), res);
489 } else {
490 *frameCount.data.i32 = mFrameCount;
491 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700492 mFrameCount++;
493 }
494
495 *buf = b;
496 mCount--;
497
498 return OK;
499}
500
501status_t Camera2Device::MetadataQueue::waitForBuffer(nsecs_t timeout)
502{
503 Mutex::Autolock l(mMutex);
504 status_t res;
505 while (mCount == 0) {
506 res = notEmpty.waitRelative(mMutex,timeout);
507 if (res != OK) return res;
508 }
509 return OK;
510}
511
512status_t Camera2Device::MetadataQueue::setStreamSlot(camera_metadata_t *buf)
513{
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700514 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700515 Mutex::Autolock l(mMutex);
516 if (buf == NULL) {
517 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
518 mStreamSlotCount = 0;
519 return OK;
520 }
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700521 camera_metadata_t *buf2 = clone_camera_metadata(buf);
522 if (!buf2) {
523 ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__);
524 return NO_MEMORY;
525 }
526
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700527 if (mStreamSlotCount > 1) {
528 List<camera_metadata_t*>::iterator deleter = ++mStreamSlot.begin();
529 freeBuffers(++mStreamSlot.begin(), mStreamSlot.end());
530 mStreamSlotCount = 1;
531 }
532 if (mStreamSlotCount == 1) {
533 free_camera_metadata( *(mStreamSlot.begin()) );
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700534 *(mStreamSlot.begin()) = buf2;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700535 } else {
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700536 mStreamSlot.push_front(buf2);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700537 mStreamSlotCount = 1;
538 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700539 return signalConsumerLocked();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700540}
541
542status_t Camera2Device::MetadataQueue::setStreamSlot(
543 const List<camera_metadata_t*> &bufs)
544{
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700545 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700546 Mutex::Autolock l(mMutex);
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700547 status_t res;
548
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700549 if (mStreamSlotCount > 0) {
550 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
551 }
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700552 mStreamSlotCount = 0;
553 for (List<camera_metadata_t*>::const_iterator r = bufs.begin();
554 r != bufs.end(); r++) {
555 camera_metadata_t *r2 = clone_camera_metadata(*r);
556 if (!r2) {
557 ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__);
558 return NO_MEMORY;
559 }
560 mStreamSlot.push_back(r2);
561 mStreamSlotCount++;
562 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700563 return signalConsumerLocked();
564}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700565
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700566status_t Camera2Device::MetadataQueue::dump(int fd,
567 const Vector<String16>& args) {
568 String8 result;
569 status_t notLocked;
570 notLocked = mMutex.tryLock();
571 if (notLocked) {
572 result.append(" (Unable to lock queue mutex)\n");
573 }
574 result.appendFormat(" Current frame number: %d\n", mFrameCount);
575 if (mStreamSlotCount == 0) {
576 result.append(" Stream slot: Empty\n");
577 write(fd, result.string(), result.size());
578 } else {
579 result.appendFormat(" Stream slot: %d entries\n",
580 mStreamSlot.size());
581 int i = 0;
582 for (List<camera_metadata_t*>::iterator r = mStreamSlot.begin();
583 r != mStreamSlot.end(); r++) {
584 result = String8::format(" Stream slot buffer %d:\n", i);
585 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700586 dump_indented_camera_metadata(*r, fd, 2, 10);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700587 i++;
588 }
589 }
590 if (mEntries.size() == 0) {
591 result = " Main queue is empty\n";
592 write(fd, result.string(), result.size());
593 } else {
594 result = String8::format(" Main queue has %d entries:\n",
595 mEntries.size());
596 int i = 0;
597 for (List<camera_metadata_t*>::iterator r = mEntries.begin();
598 r != mEntries.end(); r++) {
599 result = String8::format(" Queue entry %d:\n", i);
600 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700601 dump_indented_camera_metadata(*r, fd, 2, 10);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700602 i++;
603 }
604 }
605
606 if (notLocked == 0) {
607 mMutex.unlock();
608 }
609
610 return OK;
611}
612
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700613status_t Camera2Device::MetadataQueue::signalConsumerLocked() {
614 status_t res = OK;
615 notEmpty.signal();
616 if (mSignalConsumer && mDevice != NULL) {
617 mSignalConsumer = false;
618
619 mMutex.unlock();
620 ALOGV("%s: Signaling consumer", __FUNCTION__);
621 res = mDevice->ops->notify_request_queue_not_empty(mDevice);
622 mMutex.lock();
623 }
624 return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700625}
626
627status_t Camera2Device::MetadataQueue::freeBuffers(
628 List<camera_metadata_t*>::iterator start,
629 List<camera_metadata_t*>::iterator end)
630{
631 while (start != end) {
632 free_camera_metadata(*start);
633 start = mStreamSlot.erase(start);
634 }
635 return OK;
636}
637
638Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
639 const camera2_request_queue_src_ops_t *q)
640{
641 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
642 return const_cast<MetadataQueue*>(cmq);
643}
644
645Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
646 const camera2_frame_queue_dst_ops_t *q)
647{
648 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
649 return const_cast<MetadataQueue*>(cmq);
650}
651
652int Camera2Device::MetadataQueue::consumer_buffer_count(
653 const camera2_request_queue_src_ops_t *q)
654{
655 MetadataQueue *queue = getInstance(q);
656 return queue->getBufferCount();
657}
658
659int Camera2Device::MetadataQueue::consumer_dequeue(
660 const camera2_request_queue_src_ops_t *q,
661 camera_metadata_t **buffer)
662{
663 MetadataQueue *queue = getInstance(q);
664 return queue->dequeue(buffer, true);
665}
666
667int Camera2Device::MetadataQueue::consumer_free(
668 const camera2_request_queue_src_ops_t *q,
669 camera_metadata_t *old_buffer)
670{
671 MetadataQueue *queue = getInstance(q);
672 free_camera_metadata(old_buffer);
673 return OK;
674}
675
676int Camera2Device::MetadataQueue::producer_dequeue(
677 const camera2_frame_queue_dst_ops_t *q,
678 size_t entries, size_t bytes,
679 camera_metadata_t **buffer)
680{
681 camera_metadata_t *new_buffer =
682 allocate_camera_metadata(entries, bytes);
683 if (new_buffer == NULL) return NO_MEMORY;
684 *buffer = new_buffer;
685 return OK;
686}
687
688int Camera2Device::MetadataQueue::producer_cancel(
689 const camera2_frame_queue_dst_ops_t *q,
690 camera_metadata_t *old_buffer)
691{
692 free_camera_metadata(old_buffer);
693 return OK;
694}
695
696int Camera2Device::MetadataQueue::producer_enqueue(
697 const camera2_frame_queue_dst_ops_t *q,
698 camera_metadata_t *filled_buffer)
699{
700 MetadataQueue *queue = getInstance(q);
701 return queue->enqueue(filled_buffer);
702}
703
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700704/**
705 * Camera2Device::StreamAdapter
706 */
707
708#ifndef container_of
709#define container_of(ptr, type, member) \
710 (type *)((char*)(ptr) - offsetof(type, member))
711#endif
712
713Camera2Device::StreamAdapter::StreamAdapter(camera2_device_t *d):
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700714 mState(RELEASED),
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700715 mDevice(d),
716 mId(-1),
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700717 mWidth(0), mHeight(0), mFormat(0), mSize(0), mUsage(0),
718 mMaxProducerBuffers(0), mMaxConsumerBuffers(0),
719 mTotalBuffers(0),
720 mFormatRequested(0),
721 mActiveBuffers(0),
722 mFrameCount(0),
723 mLastTimestamp(0)
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700724{
725 camera2_stream_ops::dequeue_buffer = dequeue_buffer;
726 camera2_stream_ops::enqueue_buffer = enqueue_buffer;
727 camera2_stream_ops::cancel_buffer = cancel_buffer;
728 camera2_stream_ops::set_crop = set_crop;
729}
730
731Camera2Device::StreamAdapter::~StreamAdapter() {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700732 if (mState != RELEASED) {
733 release();
734 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700735}
736
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700737status_t Camera2Device::StreamAdapter::connectToDevice(
738 sp<ANativeWindow> consumer,
739 uint32_t width, uint32_t height, int format, size_t size) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700740 status_t res;
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700741 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700742
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700743 if (mState != RELEASED) return INVALID_OPERATION;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700744 if (consumer == NULL) {
745 ALOGE("%s: Null consumer passed to stream adapter", __FUNCTION__);
746 return BAD_VALUE;
747 }
748
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700749 ALOGV("%s: New stream parameters %d x %d, format 0x%x, size %d",
750 __FUNCTION__, width, height, format, size);
751
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700752 mConsumerInterface = consumer;
753 mWidth = width;
754 mHeight = height;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700755 mSize = (format == HAL_PIXEL_FORMAT_BLOB) ? size : 0;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700756 mFormatRequested = format;
757
758 // Allocate device-side stream interface
759
760 uint32_t id;
761 uint32_t formatActual;
762 uint32_t usage;
763 uint32_t maxBuffers = 2;
764 res = mDevice->ops->allocate_stream(mDevice,
765 mWidth, mHeight, mFormatRequested, getStreamOps(),
766 &id, &formatActual, &usage, &maxBuffers);
767 if (res != OK) {
768 ALOGE("%s: Device stream allocation failed: %s (%d)",
769 __FUNCTION__, strerror(-res), res);
770 return res;
771 }
772
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700773 ALOGV("%s: Allocated stream id %d, actual format 0x%x, "
774 "usage 0x%x, producer wants %d buffers", __FUNCTION__,
775 id, formatActual, usage, maxBuffers);
776
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700777 mId = id;
778 mFormat = formatActual;
779 mUsage = usage;
780 mMaxProducerBuffers = maxBuffers;
781
782 mState = ALLOCATED;
783
784 // Configure consumer-side ANativeWindow interface
785 res = native_window_api_connect(mConsumerInterface.get(),
786 NATIVE_WINDOW_API_CAMERA);
787 if (res != OK) {
788 ALOGE("%s: Unable to connect to native window for stream %d",
789 __FUNCTION__, mId);
790
791 return res;
792 }
793
794 mState = CONNECTED;
795
796 res = native_window_set_usage(mConsumerInterface.get(), mUsage);
797 if (res != OK) {
798 ALOGE("%s: Unable to configure usage %08x for stream %d",
799 __FUNCTION__, mUsage, mId);
800 return res;
801 }
802
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -0700803 res = native_window_set_scaling_mode(mConsumerInterface.get(),
804 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
805 if (res != OK) {
806 ALOGE("%s: Unable to configure stream scaling: %s (%d)",
807 __FUNCTION__, strerror(-res), res);
808 return res;
809 }
810
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -0700811 res = setTransform(0);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -0700812 if (res != OK) {
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -0700813 return res;
814 }
815
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700816 if (mFormat == HAL_PIXEL_FORMAT_BLOB) {
817 res = native_window_set_buffers_geometry(mConsumerInterface.get(),
818 mSize, 1, mFormat);
819 if (res != OK) {
820 ALOGE("%s: Unable to configure compressed stream buffer geometry"
821 " %d x %d, size %d for stream %d",
822 __FUNCTION__, mWidth, mHeight, mSize, mId);
823 return res;
824 }
825 } else {
826 res = native_window_set_buffers_geometry(mConsumerInterface.get(),
827 mWidth, mHeight, mFormat);
828 if (res != OK) {
829 ALOGE("%s: Unable to configure stream buffer geometry"
830 " %d x %d, format 0x%x for stream %d",
831 __FUNCTION__, mWidth, mHeight, mFormat, mId);
832 return res;
833 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700834 }
835
836 int maxConsumerBuffers;
837 res = mConsumerInterface->query(mConsumerInterface.get(),
838 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &maxConsumerBuffers);
839 if (res != OK) {
840 ALOGE("%s: Unable to query consumer undequeued"
841 " buffer count for stream %d", __FUNCTION__, mId);
842 return res;
843 }
844 mMaxConsumerBuffers = maxConsumerBuffers;
845
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700846 ALOGV("%s: Consumer wants %d buffers", __FUNCTION__,
847 mMaxConsumerBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700848
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700849 mTotalBuffers = mMaxConsumerBuffers + mMaxProducerBuffers;
850 mActiveBuffers = 0;
851 mFrameCount = 0;
852 mLastTimestamp = 0;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700853
854 res = native_window_set_buffer_count(mConsumerInterface.get(),
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700855 mTotalBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700856 if (res != OK) {
857 ALOGE("%s: Unable to set buffer count for stream %d",
858 __FUNCTION__, mId);
859 return res;
860 }
861
862 // Register allocated buffers with HAL device
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700863 buffer_handle_t *buffers = new buffer_handle_t[mTotalBuffers];
864 ANativeWindowBuffer **anwBuffers = new ANativeWindowBuffer*[mTotalBuffers];
865 uint32_t bufferIdx = 0;
866 for (; bufferIdx < mTotalBuffers; bufferIdx++) {
Jamie Gennis1e5b2b32012-06-13 16:29:51 -0700867 res = native_window_dequeue_buffer_and_wait(mConsumerInterface.get(),
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700868 &anwBuffers[bufferIdx]);
869 if (res != OK) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700870 ALOGE("%s: Unable to dequeue buffer %d for initial registration for "
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700871 "stream %d", __FUNCTION__, bufferIdx, mId);
872 goto cleanUpBuffers;
873 }
874
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700875 buffers[bufferIdx] = anwBuffers[bufferIdx]->handle;
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -0700876 ALOGV("%s: Buffer %p allocated", __FUNCTION__, (void*)(buffers[bufferIdx]));
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700877 }
878
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -0700879 ALOGV("%s: Registering %d buffers with camera HAL", __FUNCTION__, mTotalBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700880 res = mDevice->ops->register_stream_buffers(mDevice,
881 mId,
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700882 mTotalBuffers,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700883 buffers);
884 if (res != OK) {
885 ALOGE("%s: Unable to register buffers with HAL device for stream %d",
886 __FUNCTION__, mId);
887 } else {
888 mState = ACTIVE;
889 }
890
891cleanUpBuffers:
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -0700892 ALOGV("%s: Cleaning up %d buffers", __FUNCTION__, bufferIdx);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700893 for (uint32_t i = 0; i < bufferIdx; i++) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700894 res = mConsumerInterface->cancelBuffer(mConsumerInterface.get(),
Jamie Gennis1e5b2b32012-06-13 16:29:51 -0700895 anwBuffers[i], -1);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700896 if (res != OK) {
897 ALOGE("%s: Unable to cancel buffer %d after registration",
898 __FUNCTION__, i);
899 }
900 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700901 delete[] anwBuffers;
902 delete[] buffers;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700903
904 return res;
905}
906
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700907status_t Camera2Device::StreamAdapter::release() {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700908 status_t res;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700909 ALOGV("%s: Releasing stream %d", __FUNCTION__, mId);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700910 if (mState >= ALLOCATED) {
911 res = mDevice->ops->release_stream(mDevice, mId);
912 if (res != OK) {
913 ALOGE("%s: Unable to release stream %d",
914 __FUNCTION__, mId);
915 return res;
916 }
917 }
918 if (mState >= CONNECTED) {
919 res = native_window_api_disconnect(mConsumerInterface.get(),
920 NATIVE_WINDOW_API_CAMERA);
921 if (res != OK) {
922 ALOGE("%s: Unable to disconnect stream %d from native window",
923 __FUNCTION__, mId);
924 return res;
925 }
926 }
927 mId = -1;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700928 mState = RELEASED;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700929 return OK;
930}
931
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -0700932status_t Camera2Device::StreamAdapter::setTransform(int transform) {
933 status_t res;
934 if (mState < CONNECTED) {
935 ALOGE("%s: Cannot set transform on unconnected stream", __FUNCTION__);
936 return INVALID_OPERATION;
937 }
938 res = native_window_set_buffers_transform(mConsumerInterface.get(),
939 transform);
940 if (res != OK) {
941 ALOGE("%s: Unable to configure stream transform to %x: %s (%d)",
942 __FUNCTION__, transform, strerror(-res), res);
943 }
944 return res;
945}
946
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700947status_t Camera2Device::StreamAdapter::dump(int fd,
948 const Vector<String16>& args) {
949 String8 result = String8::format(" Stream %d: %d x %d, format 0x%x\n",
950 mId, mWidth, mHeight, mFormat);
951 result.appendFormat(" size %d, usage 0x%x, requested format 0x%x\n",
952 mSize, mUsage, mFormatRequested);
953 result.appendFormat(" total buffers: %d, dequeued buffers: %d\n",
954 mTotalBuffers, mActiveBuffers);
955 result.appendFormat(" frame count: %d, last timestamp %lld\n",
956 mFrameCount, mLastTimestamp);
957 write(fd, result.string(), result.size());
958 return OK;
959}
960
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700961const camera2_stream_ops *Camera2Device::StreamAdapter::getStreamOps() {
962 return static_cast<camera2_stream_ops *>(this);
963}
964
965ANativeWindow* Camera2Device::StreamAdapter::toANW(
966 const camera2_stream_ops_t *w) {
967 return static_cast<const StreamAdapter*>(w)->mConsumerInterface.get();
968}
969
970int Camera2Device::StreamAdapter::dequeue_buffer(const camera2_stream_ops_t *w,
971 buffer_handle_t** buffer) {
972 int res;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700973 StreamAdapter* stream =
974 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
975 if (stream->mState != ACTIVE) {
976 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700977 return INVALID_OPERATION;
978 }
979
980 ANativeWindow *a = toANW(w);
981 ANativeWindowBuffer* anb;
Jamie Gennis1e5b2b32012-06-13 16:29:51 -0700982 res = native_window_dequeue_buffer_and_wait(a, &anb);
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -0700983 if (res != OK) {
984 ALOGE("Stream %d dequeue: Error from native_window: %s (%d)", stream->mId,
985 strerror(-res), res);
986 return res;
987 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700988
989 *buffer = &(anb->handle);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700990 stream->mActiveBuffers++;
991
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -0700992 ALOGVV("Stream %d dequeue: Buffer %p dequeued", stream->mId, (void*)(**buffer));
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700993 return res;
994}
995
996int Camera2Device::StreamAdapter::enqueue_buffer(const camera2_stream_ops_t* w,
997 int64_t timestamp,
998 buffer_handle_t* buffer) {
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700999 StreamAdapter *stream =
1000 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001001 ALOGVV("Stream %d enqueue: Buffer %p captured at %lld ns",
1002 stream->mId, (void*)(*buffer), timestamp);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001003 int state = stream->mState;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001004 if (state != ACTIVE) {
1005 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1006 return INVALID_OPERATION;
1007 }
1008 ANativeWindow *a = toANW(w);
1009 status_t err;
1010 err = native_window_set_buffers_timestamp(a, timestamp);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001011 if (err != OK) {
1012 ALOGE("%s: Error setting timestamp on native window: %s (%d)",
1013 __FUNCTION__, strerror(-err), err);
1014 return err;
1015 }
1016 err = a->queueBuffer(a,
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001017 container_of(buffer, ANativeWindowBuffer, handle), -1);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001018 if (err != OK) {
1019 ALOGE("%s: Error queueing buffer to native window: %s (%d)",
1020 __FUNCTION__, strerror(-err), err);
James Dong31d377b2012-08-09 17:43:46 -07001021 return err;
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001022 }
James Dong31d377b2012-08-09 17:43:46 -07001023
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001024 stream->mActiveBuffers--;
1025 stream->mFrameCount++;
1026 stream->mLastTimestamp = timestamp;
James Dong31d377b2012-08-09 17:43:46 -07001027 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001028}
1029
1030int Camera2Device::StreamAdapter::cancel_buffer(const camera2_stream_ops_t* w,
1031 buffer_handle_t* buffer) {
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001032 StreamAdapter *stream =
1033 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001034 ALOGVV("Stream %d cancel: Buffer %p",
1035 stream->mId, (void*)(*buffer));
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001036 if (stream->mState != ACTIVE) {
1037 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001038 return INVALID_OPERATION;
1039 }
James Dong31d377b2012-08-09 17:43:46 -07001040
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001041 ANativeWindow *a = toANW(w);
James Dong31d377b2012-08-09 17:43:46 -07001042 int err = a->cancelBuffer(a,
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001043 container_of(buffer, ANativeWindowBuffer, handle), -1);
James Dong31d377b2012-08-09 17:43:46 -07001044 if (err != OK) {
1045 ALOGE("%s: Error canceling buffer to native window: %s (%d)",
1046 __FUNCTION__, strerror(-err), err);
1047 return err;
1048 }
1049
1050 stream->mActiveBuffers--;
1051 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001052}
1053
1054int Camera2Device::StreamAdapter::set_crop(const camera2_stream_ops_t* w,
1055 int left, int top, int right, int bottom) {
1056 int state = static_cast<const StreamAdapter*>(w)->mState;
1057 if (state != ACTIVE) {
1058 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1059 return INVALID_OPERATION;
1060 }
1061 ANativeWindow *a = toANW(w);
1062 android_native_rect_t crop = { left, top, right, bottom };
1063 return native_window_set_crop(a, &crop);
1064}
1065
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001066
1067}; // namespace android