blob: b81d54c08c8917d4635f245934d4e34ae2db2da7 [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
19
20#include <utils/Log.h>
21#include "Camera2Device.h"
22
23namespace android {
24
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070025Camera2Device::Camera2Device(int id):
26 mId(id),
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070027 mDevice(NULL)
28{
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -070029 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070030}
31
32Camera2Device::~Camera2Device()
33{
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -070034 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070035 if (mDevice) {
36 status_t res;
37 res = mDevice->common.close(&mDevice->common);
38 if (res != OK) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070039 ALOGE("%s: Could not close camera %d: %s (%d)",
40 __FUNCTION__,
41 mId, strerror(-res), res);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070042 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070043 mDevice = NULL;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070044 }
45}
46
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070047status_t Camera2Device::initialize(camera_module_t *module)
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070048{
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -070049 ALOGV("%s: E", __FUNCTION__);
50
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070051 status_t res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070052 char name[10];
53 snprintf(name, sizeof(name), "%d", mId);
54
55 res = module->common.methods->open(&module->common, name,
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070056 reinterpret_cast<hw_device_t**>(&mDevice));
57
58 if (res != OK) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070059 ALOGE("%s: Could not open camera %d: %s (%d)", __FUNCTION__,
60 mId, strerror(-res), res);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070061 return res;
62 }
63
64 if (mDevice->common.version != CAMERA_DEVICE_API_VERSION_2_0) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070065 ALOGE("%s: Could not open camera %d: "
66 "Camera device is not version %x, reports %x instead",
67 __FUNCTION__, mId, CAMERA_DEVICE_API_VERSION_2_0,
68 mDevice->common.version);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070069 return BAD_VALUE;
70 }
71
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070072 camera_info info;
73 res = module->get_camera_info(mId, &info);
74 if (res != OK ) return res;
75
76 if (info.device_version != mDevice->common.version) {
77 ALOGE("%s: HAL reporting mismatched camera_info version (%x)"
78 " and device version (%x).", __FUNCTION__,
79 mDevice->common.version, info.device_version);
80 return BAD_VALUE;
81 }
82
83 mDeviceInfo = info.static_camera_characteristics;
84
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -070085 res = mRequestQueue.setConsumerDevice(mDevice);
86 if (res != OK) {
87 ALOGE("%s: Camera %d: Unable to connect request queue to device: %s (%d)",
88 __FUNCTION__, mId, strerror(-res), res);
89 return res;
90 }
91 res = mFrameQueue.setProducerDevice(mDevice);
92 if (res != OK) {
93 ALOGE("%s: Camera %d: Unable to connect frame queue to device: %s (%d)",
94 __FUNCTION__, mId, strerror(-res), res);
95 return res;
96 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070097
98 res = mDevice->ops->get_metadata_vendor_tag_ops(mDevice, &mVendorTagOps);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -070099 if (res != OK ) {
100 ALOGE("%s: Camera %d: Unable to retrieve tag ops from device: %s (%d)",
101 __FUNCTION__, mId, strerror(-res), res);
102 return res;
103 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700104
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700105 return OK;
106}
107
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700108camera_metadata_t *Camera2Device::info() {
109 ALOGV("%s: E", __FUNCTION__);
110
111 return mDeviceInfo;
112}
113
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700114status_t Camera2Device::setStreamingRequest(camera_metadata_t* request)
115{
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700116 ALOGV("%s: E", __FUNCTION__);
117
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700118 mRequestQueue.setStreamSlot(request);
119 return OK;
120}
121
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700122status_t Camera2Device::createStream(sp<ANativeWindow> consumer,
123 uint32_t width, uint32_t height, int format, int *id) {
124 status_t res;
125 ALOGV("%s: E", __FUNCTION__);
126
127 sp<StreamAdapter> stream = new StreamAdapter(mDevice);
128
129 res = stream->connectToDevice(consumer, width, height, format);
130 if (res != OK) {
131 ALOGE("%s: Camera %d: Unable to create stream (%d x %d, format %x):"
132 "%s (%d)",
133 __FUNCTION__, mId, width, height, format, strerror(-res), res);
134 return res;
135 }
136
137 *id = stream->getId();
138
139 mStreams.push_back(stream);
140 return OK;
141}
142
143status_t Camera2Device::deleteStream(int id) {
144 ALOGV("%s: E", __FUNCTION__);
145
146 bool found = false;
147 for (StreamList::iterator streamI = mStreams.begin();
148 streamI != mStreams.end(); streamI++) {
149 if ((*streamI)->getId() == id) {
150 mStreams.erase(streamI);
151 found = true;
152 break;
153 }
154 }
155 if (!found) {
156 ALOGE("%s: Camera %d: Unable to find stream %d to delete",
157 __FUNCTION__, mId, id);
158 return BAD_VALUE;
159 }
160 return OK;
161}
162
163status_t Camera2Device::createDefaultRequest(int templateId,
164 camera_metadata_t **request) {
165 ALOGV("%s: E", __FUNCTION__);
166 return mDevice->ops->construct_default_request(mDevice, templateId, request);
167}
168
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700169/**
170 * Camera2Device::MetadataQueue
171 */
172
173Camera2Device::MetadataQueue::MetadataQueue():
174 mDevice(NULL),
175 mFrameCount(0),
176 mCount(0),
177 mStreamSlotCount(0),
178 mSignalConsumer(true)
179{
180 camera2_request_queue_src_ops::dequeue_request = consumer_dequeue;
181 camera2_request_queue_src_ops::request_count = consumer_buffer_count;
182 camera2_request_queue_src_ops::free_request = consumer_free;
183
184 camera2_frame_queue_dst_ops::dequeue_frame = producer_dequeue;
185 camera2_frame_queue_dst_ops::cancel_frame = producer_cancel;
186 camera2_frame_queue_dst_ops::enqueue_frame = producer_enqueue;
187}
188
189Camera2Device::MetadataQueue::~MetadataQueue() {
190 Mutex::Autolock l(mMutex);
191 freeBuffers(mEntries.begin(), mEntries.end());
192 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
193}
194
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700195// Connect to camera2 HAL as consumer (input requests/reprocessing)
196status_t Camera2Device::MetadataQueue::setConsumerDevice(camera2_device_t *d) {
197 status_t res;
198 res = d->ops->set_request_queue_src_ops(d,
199 this);
200 if (res != OK) return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700201 mDevice = d;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700202 return OK;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700203}
204
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700205status_t Camera2Device::MetadataQueue::setProducerDevice(camera2_device_t *d) {
206 status_t res;
207 res = d->ops->set_frame_queue_dst_ops(d,
208 this);
209 return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700210}
211
212// Real interfaces
213status_t Camera2Device::MetadataQueue::enqueue(camera_metadata_t *buf) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700214 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700215 Mutex::Autolock l(mMutex);
216
217 mCount++;
218 mEntries.push_back(buf);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700219
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700220 return signalConsumerLocked();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700221}
222
223int Camera2Device::MetadataQueue::getBufferCount() {
224 Mutex::Autolock l(mMutex);
225 if (mStreamSlotCount > 0) {
226 return CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS;
227 }
228 return mCount;
229}
230
231status_t Camera2Device::MetadataQueue::dequeue(camera_metadata_t **buf,
232 bool incrementCount)
233{
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700234 ALOGV("%s: E", __FUNCTION__);
235 status_t res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700236 Mutex::Autolock l(mMutex);
237
238 if (mCount == 0) {
239 if (mStreamSlotCount == 0) {
240 ALOGV("%s: Empty", __FUNCTION__);
241 *buf = NULL;
242 mSignalConsumer = true;
243 return OK;
244 }
245 ALOGV("%s: Streaming %d frames to queue", __FUNCTION__,
246 mStreamSlotCount);
247
248 for (List<camera_metadata_t*>::iterator slotEntry = mStreamSlot.begin();
249 slotEntry != mStreamSlot.end();
250 slotEntry++ ) {
251 size_t entries = get_camera_metadata_entry_count(*slotEntry);
252 size_t dataBytes = get_camera_metadata_data_count(*slotEntry);
253
254 camera_metadata_t *copy =
255 allocate_camera_metadata(entries, dataBytes);
256 append_camera_metadata(copy, *slotEntry);
257 mEntries.push_back(copy);
258 }
259 mCount = mStreamSlotCount;
260 }
261 ALOGV("MetadataQueue: deque (%d buffers)", mCount);
262 camera_metadata_t *b = *(mEntries.begin());
263 mEntries.erase(mEntries.begin());
264
265 if (incrementCount) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700266 camera_metadata_entry_t frameCount;
267 res = find_camera_metadata_entry(b,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700268 ANDROID_REQUEST_FRAME_COUNT,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700269 &frameCount);
270 if (res != OK) {
271 ALOGE("%s: Unable to add frame count: %s (%d)",
272 __FUNCTION__, strerror(-res), res);
273 } else {
274 *frameCount.data.i32 = mFrameCount;
275 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700276 mFrameCount++;
277 }
278
279 *buf = b;
280 mCount--;
281
282 return OK;
283}
284
285status_t Camera2Device::MetadataQueue::waitForBuffer(nsecs_t timeout)
286{
287 Mutex::Autolock l(mMutex);
288 status_t res;
289 while (mCount == 0) {
290 res = notEmpty.waitRelative(mMutex,timeout);
291 if (res != OK) return res;
292 }
293 return OK;
294}
295
296status_t Camera2Device::MetadataQueue::setStreamSlot(camera_metadata_t *buf)
297{
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700298 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700299 Mutex::Autolock l(mMutex);
300 if (buf == NULL) {
301 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
302 mStreamSlotCount = 0;
303 return OK;
304 }
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700305 camera_metadata_t *buf2 = clone_camera_metadata(buf);
306 if (!buf2) {
307 ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__);
308 return NO_MEMORY;
309 }
310
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700311 if (mStreamSlotCount > 1) {
312 List<camera_metadata_t*>::iterator deleter = ++mStreamSlot.begin();
313 freeBuffers(++mStreamSlot.begin(), mStreamSlot.end());
314 mStreamSlotCount = 1;
315 }
316 if (mStreamSlotCount == 1) {
317 free_camera_metadata( *(mStreamSlot.begin()) );
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700318 *(mStreamSlot.begin()) = buf2;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700319 } else {
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700320 mStreamSlot.push_front(buf2);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700321 mStreamSlotCount = 1;
322 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700323 return signalConsumerLocked();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700324}
325
326status_t Camera2Device::MetadataQueue::setStreamSlot(
327 const List<camera_metadata_t*> &bufs)
328{
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700329 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700330 Mutex::Autolock l(mMutex);
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700331 status_t res;
332
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700333 if (mStreamSlotCount > 0) {
334 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
335 }
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700336 mStreamSlotCount = 0;
337 for (List<camera_metadata_t*>::const_iterator r = bufs.begin();
338 r != bufs.end(); r++) {
339 camera_metadata_t *r2 = clone_camera_metadata(*r);
340 if (!r2) {
341 ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__);
342 return NO_MEMORY;
343 }
344 mStreamSlot.push_back(r2);
345 mStreamSlotCount++;
346 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700347 return signalConsumerLocked();
348}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700349
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700350status_t Camera2Device::MetadataQueue::signalConsumerLocked() {
351 status_t res = OK;
352 notEmpty.signal();
353 if (mSignalConsumer && mDevice != NULL) {
354 mSignalConsumer = false;
355
356 mMutex.unlock();
357 ALOGV("%s: Signaling consumer", __FUNCTION__);
358 res = mDevice->ops->notify_request_queue_not_empty(mDevice);
359 mMutex.lock();
360 }
361 return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700362}
363
364status_t Camera2Device::MetadataQueue::freeBuffers(
365 List<camera_metadata_t*>::iterator start,
366 List<camera_metadata_t*>::iterator end)
367{
368 while (start != end) {
369 free_camera_metadata(*start);
370 start = mStreamSlot.erase(start);
371 }
372 return OK;
373}
374
375Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
376 const camera2_request_queue_src_ops_t *q)
377{
378 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
379 return const_cast<MetadataQueue*>(cmq);
380}
381
382Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
383 const camera2_frame_queue_dst_ops_t *q)
384{
385 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
386 return const_cast<MetadataQueue*>(cmq);
387}
388
389int Camera2Device::MetadataQueue::consumer_buffer_count(
390 const camera2_request_queue_src_ops_t *q)
391{
392 MetadataQueue *queue = getInstance(q);
393 return queue->getBufferCount();
394}
395
396int Camera2Device::MetadataQueue::consumer_dequeue(
397 const camera2_request_queue_src_ops_t *q,
398 camera_metadata_t **buffer)
399{
400 MetadataQueue *queue = getInstance(q);
401 return queue->dequeue(buffer, true);
402}
403
404int Camera2Device::MetadataQueue::consumer_free(
405 const camera2_request_queue_src_ops_t *q,
406 camera_metadata_t *old_buffer)
407{
408 MetadataQueue *queue = getInstance(q);
409 free_camera_metadata(old_buffer);
410 return OK;
411}
412
413int Camera2Device::MetadataQueue::producer_dequeue(
414 const camera2_frame_queue_dst_ops_t *q,
415 size_t entries, size_t bytes,
416 camera_metadata_t **buffer)
417{
418 camera_metadata_t *new_buffer =
419 allocate_camera_metadata(entries, bytes);
420 if (new_buffer == NULL) return NO_MEMORY;
421 *buffer = new_buffer;
422 return OK;
423}
424
425int Camera2Device::MetadataQueue::producer_cancel(
426 const camera2_frame_queue_dst_ops_t *q,
427 camera_metadata_t *old_buffer)
428{
429 free_camera_metadata(old_buffer);
430 return OK;
431}
432
433int Camera2Device::MetadataQueue::producer_enqueue(
434 const camera2_frame_queue_dst_ops_t *q,
435 camera_metadata_t *filled_buffer)
436{
437 MetadataQueue *queue = getInstance(q);
438 return queue->enqueue(filled_buffer);
439}
440
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700441/**
442 * Camera2Device::StreamAdapter
443 */
444
445#ifndef container_of
446#define container_of(ptr, type, member) \
447 (type *)((char*)(ptr) - offsetof(type, member))
448#endif
449
450Camera2Device::StreamAdapter::StreamAdapter(camera2_device_t *d):
451 mState(DISCONNECTED),
452 mDevice(d),
453 mId(-1),
454 mWidth(0), mHeight(0), mFormatRequested(0)
455{
456 camera2_stream_ops::dequeue_buffer = dequeue_buffer;
457 camera2_stream_ops::enqueue_buffer = enqueue_buffer;
458 camera2_stream_ops::cancel_buffer = cancel_buffer;
459 camera2_stream_ops::set_crop = set_crop;
460}
461
462Camera2Device::StreamAdapter::~StreamAdapter() {
463 disconnect();
464}
465
466status_t Camera2Device::StreamAdapter::connectToDevice(sp<ANativeWindow> consumer,
467 uint32_t width, uint32_t height, int format) {
468 status_t res;
469
470 if (mState != DISCONNECTED) return INVALID_OPERATION;
471 if (consumer == NULL) {
472 ALOGE("%s: Null consumer passed to stream adapter", __FUNCTION__);
473 return BAD_VALUE;
474 }
475
476 mConsumerInterface = consumer;
477 mWidth = width;
478 mHeight = height;
479 mFormatRequested = format;
480
481 // Allocate device-side stream interface
482
483 uint32_t id;
484 uint32_t formatActual;
485 uint32_t usage;
486 uint32_t maxBuffers = 2;
487 res = mDevice->ops->allocate_stream(mDevice,
488 mWidth, mHeight, mFormatRequested, getStreamOps(),
489 &id, &formatActual, &usage, &maxBuffers);
490 if (res != OK) {
491 ALOGE("%s: Device stream allocation failed: %s (%d)",
492 __FUNCTION__, strerror(-res), res);
493 return res;
494 }
495
496 mId = id;
497 mFormat = formatActual;
498 mUsage = usage;
499 mMaxProducerBuffers = maxBuffers;
500
501 mState = ALLOCATED;
502
503 // Configure consumer-side ANativeWindow interface
504 res = native_window_api_connect(mConsumerInterface.get(),
505 NATIVE_WINDOW_API_CAMERA);
506 if (res != OK) {
507 ALOGE("%s: Unable to connect to native window for stream %d",
508 __FUNCTION__, mId);
509
510 return res;
511 }
512
513 mState = CONNECTED;
514
515 res = native_window_set_usage(mConsumerInterface.get(), mUsage);
516 if (res != OK) {
517 ALOGE("%s: Unable to configure usage %08x for stream %d",
518 __FUNCTION__, mUsage, mId);
519 return res;
520 }
521
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -0700522 res = native_window_set_scaling_mode(mConsumerInterface.get(),
523 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
524 if (res != OK) {
525 ALOGE("%s: Unable to configure stream scaling: %s (%d)",
526 __FUNCTION__, strerror(-res), res);
527 return res;
528 }
529
530 res = native_window_set_buffers_transform(mConsumerInterface.get(), 0);
531 if (res != OK) {
532 ALOGE("%s: Unable to configure stream transform: %s (%d)",
533 __FUNCTION__, strerror(-res), res);
534 return res;
535 }
536
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700537 res = native_window_set_buffers_geometry(mConsumerInterface.get(),
538 mWidth, mHeight, mFormat);
539 if (res != OK) {
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -0700540 ALOGE("%s: Unable to configure stream buffer geometry"
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700541 " %d x %d, format 0x%x for stream %d",
542 __FUNCTION__, mWidth, mHeight, mFormat, mId);
543 return res;
544 }
545
546 int maxConsumerBuffers;
547 res = mConsumerInterface->query(mConsumerInterface.get(),
548 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &maxConsumerBuffers);
549 if (res != OK) {
550 ALOGE("%s: Unable to query consumer undequeued"
551 " buffer count for stream %d", __FUNCTION__, mId);
552 return res;
553 }
554 mMaxConsumerBuffers = maxConsumerBuffers;
555
556 ALOGV("%s: Producer wants %d buffers, consumer wants %d", __FUNCTION__,
557 mMaxProducerBuffers, mMaxConsumerBuffers);
558
559 int totalBuffers = mMaxConsumerBuffers + mMaxProducerBuffers;
560
561 res = native_window_set_buffer_count(mConsumerInterface.get(),
562 totalBuffers);
563 if (res != OK) {
564 ALOGE("%s: Unable to set buffer count for stream %d",
565 __FUNCTION__, mId);
566 return res;
567 }
568
569 // Register allocated buffers with HAL device
570 buffer_handle_t *buffers = new buffer_handle_t[totalBuffers];
571 ANativeWindowBuffer **anwBuffers = new ANativeWindowBuffer*[totalBuffers];
572 int bufferIdx = 0;
573 for (; bufferIdx < totalBuffers; bufferIdx++) {
574 res = mConsumerInterface->dequeueBuffer(mConsumerInterface.get(),
575 &anwBuffers[bufferIdx]);
576 if (res != OK) {
577 ALOGE("%s: Unable to dequeue buffer %d for initial registration for"
578 "stream %d", __FUNCTION__, bufferIdx, mId);
579 goto cleanUpBuffers;
580 }
581
582 res = mConsumerInterface->lockBuffer(mConsumerInterface.get(),
583 anwBuffers[bufferIdx]);
584 if (res != OK) {
585 ALOGE("%s: Unable to lock buffer %d for initial registration for"
586 "stream %d", __FUNCTION__, bufferIdx, mId);
587 bufferIdx++;
588 goto cleanUpBuffers;
589 }
590
591 buffers[bufferIdx] = anwBuffers[bufferIdx]->handle;
592 }
593
594 res = mDevice->ops->register_stream_buffers(mDevice,
595 mId,
596 totalBuffers,
597 buffers);
598 if (res != OK) {
599 ALOGE("%s: Unable to register buffers with HAL device for stream %d",
600 __FUNCTION__, mId);
601 } else {
602 mState = ACTIVE;
603 }
604
605cleanUpBuffers:
606 for (int i = 0; i < bufferIdx; i++) {
607 res = mConsumerInterface->cancelBuffer(mConsumerInterface.get(),
608 anwBuffers[i]);
609 if (res != OK) {
610 ALOGE("%s: Unable to cancel buffer %d after registration",
611 __FUNCTION__, i);
612 }
613 }
614 delete anwBuffers;
615 delete buffers;
616
617 return res;
618}
619
620status_t Camera2Device::StreamAdapter::disconnect() {
621 status_t res;
622 if (mState >= ALLOCATED) {
623 res = mDevice->ops->release_stream(mDevice, mId);
624 if (res != OK) {
625 ALOGE("%s: Unable to release stream %d",
626 __FUNCTION__, mId);
627 return res;
628 }
629 }
630 if (mState >= CONNECTED) {
631 res = native_window_api_disconnect(mConsumerInterface.get(),
632 NATIVE_WINDOW_API_CAMERA);
633 if (res != OK) {
634 ALOGE("%s: Unable to disconnect stream %d from native window",
635 __FUNCTION__, mId);
636 return res;
637 }
638 }
639 mId = -1;
640 mState = DISCONNECTED;
641 return OK;
642}
643
644int Camera2Device::StreamAdapter::getId() {
645 return mId;
646}
647
648const camera2_stream_ops *Camera2Device::StreamAdapter::getStreamOps() {
649 return static_cast<camera2_stream_ops *>(this);
650}
651
652ANativeWindow* Camera2Device::StreamAdapter::toANW(
653 const camera2_stream_ops_t *w) {
654 return static_cast<const StreamAdapter*>(w)->mConsumerInterface.get();
655}
656
657int Camera2Device::StreamAdapter::dequeue_buffer(const camera2_stream_ops_t *w,
658 buffer_handle_t** buffer) {
659 int res;
660 int state = static_cast<const StreamAdapter*>(w)->mState;
661 if (state != ACTIVE) {
662 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
663 return INVALID_OPERATION;
664 }
665
666 ANativeWindow *a = toANW(w);
667 ANativeWindowBuffer* anb;
668 res = a->dequeueBuffer(a, &anb);
669 if (res != OK) return res;
670 res = a->lockBuffer(a, anb);
671 if (res != OK) return res;
672
673 *buffer = &(anb->handle);
674 ALOGV("%s: Buffer %p", __FUNCTION__, *buffer);
675 return res;
676}
677
678int Camera2Device::StreamAdapter::enqueue_buffer(const camera2_stream_ops_t* w,
679 int64_t timestamp,
680 buffer_handle_t* buffer) {
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -0700681 const StreamAdapter *stream = static_cast<const StreamAdapter*>(w);
682 ALOGV("%s: Stream %d: Buffer %p captured at %lld ns",
683 __FUNCTION__, stream->mId, buffer, timestamp);
684 int state = stream->mState;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700685 if (state != ACTIVE) {
686 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
687 return INVALID_OPERATION;
688 }
689 ANativeWindow *a = toANW(w);
690 status_t err;
691 err = native_window_set_buffers_timestamp(a, timestamp);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -0700692 if (err != OK) {
693 ALOGE("%s: Error setting timestamp on native window: %s (%d)",
694 __FUNCTION__, strerror(-err), err);
695 return err;
696 }
697 err = a->queueBuffer(a,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700698 container_of(buffer, ANativeWindowBuffer, handle));
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -0700699 if (err != OK) {
700 ALOGE("%s: Error queueing buffer to native window: %s (%d)",
701 __FUNCTION__, strerror(-err), err);
702 }
703 return err;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700704}
705
706int Camera2Device::StreamAdapter::cancel_buffer(const camera2_stream_ops_t* w,
707 buffer_handle_t* buffer) {
708 int state = static_cast<const StreamAdapter*>(w)->mState;
709 if (state != ACTIVE) {
710 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
711 return INVALID_OPERATION;
712 }
713 ANativeWindow *a = toANW(w);
714 return a->cancelBuffer(a,
715 container_of(buffer, ANativeWindowBuffer, handle));
716}
717
718int Camera2Device::StreamAdapter::set_crop(const camera2_stream_ops_t* w,
719 int left, int top, int right, int bottom) {
720 int state = static_cast<const StreamAdapter*>(w)->mState;
721 if (state != ACTIVE) {
722 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
723 return INVALID_OPERATION;
724 }
725 ANativeWindow *a = toANW(w);
726 android_native_rect_t crop = { left, top, right, bottom };
727 return native_window_set_crop(a, &crop);
728}
729
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700730
731}; // namespace android