blob: f6253d23ce837facf2d289a5b3638f50808e8666 [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;
120
121 result.appendFormat(" Camera2Device[%d] dump:\n", mId);
122
123 result.appendFormat(" Static camera information metadata:\n");
124 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700125 dump_indented_camera_metadata(mDeviceInfo, fd, 2, 6);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700126
127 result = " Request queue contents:\n";
128 write(fd, result.string(), result.size());
129 mRequestQueue.dump(fd, args);
130
131 result = " Frame queue contents:\n";
132 write(fd, result.string(), result.size());
133 mFrameQueue.dump(fd, args);
134
135 result = " Active streams:\n";
136 write(fd, result.string(), result.size());
137 for (StreamList::iterator s = mStreams.begin(); s != mStreams.end(); s++) {
138 (*s)->dump(fd, args);
139 }
140
141 result = " HAL device dump:\n";
142 write(fd, result.string(), result.size());
143
144 status_t res;
145 res = mDevice->ops->dump(mDevice, fd);
146
147 return res;
148}
149
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700150camera_metadata_t *Camera2Device::info() {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700151 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700152
153 return mDeviceInfo;
154}
155
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700156status_t Camera2Device::capture(camera_metadata_t* request) {
157 ALOGV("%s: E", __FUNCTION__);
158
159 mRequestQueue.enqueue(request);
160 return OK;
161}
162
163
164status_t Camera2Device::setStreamingRequest(camera_metadata_t* request) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700165 ALOGV("%s: E", __FUNCTION__);
166
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700167 mRequestQueue.setStreamSlot(request);
168 return OK;
169}
170
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700171status_t Camera2Device::createStream(sp<ANativeWindow> consumer,
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700172 uint32_t width, uint32_t height, int format, size_t size, int *id) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700173 status_t res;
174 ALOGV("%s: E", __FUNCTION__);
175
176 sp<StreamAdapter> stream = new StreamAdapter(mDevice);
177
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700178 res = stream->connectToDevice(consumer, width, height, format, size);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700179 if (res != OK) {
180 ALOGE("%s: Camera %d: Unable to create stream (%d x %d, format %x):"
181 "%s (%d)",
182 __FUNCTION__, mId, width, height, format, strerror(-res), res);
183 return res;
184 }
185
186 *id = stream->getId();
187
188 mStreams.push_back(stream);
189 return OK;
190}
191
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700192status_t Camera2Device::getStreamInfo(int id,
193 uint32_t *width, uint32_t *height, uint32_t *format) {
194 ALOGV("%s: E", __FUNCTION__);
195 bool found = false;
196 StreamList::iterator streamI;
197 for (streamI = mStreams.begin();
198 streamI != mStreams.end(); streamI++) {
199 if ((*streamI)->getId() == id) {
200 found = true;
201 break;
202 }
203 }
204 if (!found) {
205 ALOGE("%s: Camera %d: Stream %d does not exist",
206 __FUNCTION__, mId, id);
207 return BAD_VALUE;
208 }
209
210 if (width) *width = (*streamI)->getWidth();
211 if (height) *height = (*streamI)->getHeight();
212 if (format) *format = (*streamI)->getFormat();
213
214 return OK;
215}
216
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -0700217status_t Camera2Device::setStreamTransform(int id,
218 int transform) {
219 ALOGV("%s: E", __FUNCTION__);
220 bool found = false;
221 StreamList::iterator streamI;
222 for (streamI = mStreams.begin();
223 streamI != mStreams.end(); streamI++) {
224 if ((*streamI)->getId() == id) {
225 found = true;
226 break;
227 }
228 }
229 if (!found) {
230 ALOGE("%s: Camera %d: Stream %d does not exist",
231 __FUNCTION__, mId, id);
232 return BAD_VALUE;
233 }
234
235 return (*streamI)->setTransform(transform);
236}
237
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700238status_t Camera2Device::deleteStream(int id) {
239 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700240 bool found = false;
241 for (StreamList::iterator streamI = mStreams.begin();
242 streamI != mStreams.end(); streamI++) {
243 if ((*streamI)->getId() == id) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700244 status_t res = (*streamI)->release();
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700245 if (res != OK) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700246 ALOGE("%s: Unable to release stream %d from HAL device: "
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700247 "%s (%d)", __FUNCTION__, id, strerror(-res), res);
248 return res;
249 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700250 mStreams.erase(streamI);
251 found = true;
252 break;
253 }
254 }
255 if (!found) {
256 ALOGE("%s: Camera %d: Unable to find stream %d to delete",
257 __FUNCTION__, mId, id);
258 return BAD_VALUE;
259 }
260 return OK;
261}
262
263status_t Camera2Device::createDefaultRequest(int templateId,
264 camera_metadata_t **request) {
265 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700266 return mDevice->ops->construct_default_request(
267 mDevice, templateId, request);
268}
269
270status_t Camera2Device::waitUntilDrained() {
271 static const uint32_t kSleepTime = 50000; // 50 ms
272 static const uint32_t kMaxSleepTime = 10000000; // 10 s
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700273 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700274 if (mRequestQueue.getBufferCount() ==
275 CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS) return INVALID_OPERATION;
276
277 // TODO: Set up notifications from HAL, instead of sleeping here
278 uint32_t totalTime = 0;
279 while (mDevice->ops->get_in_progress_count(mDevice) > 0) {
280 usleep(kSleepTime);
281 totalTime += kSleepTime;
282 if (totalTime > kMaxSleepTime) {
283 ALOGE("%s: Waited %d us, requests still in flight", __FUNCTION__,
284 totalTime);
285 return TIMED_OUT;
286 }
287 }
288 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700289}
290
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700291status_t Camera2Device::setNotifyCallback(NotificationListener *listener) {
292 status_t res;
293 res = mDevice->ops->set_notify_callback(mDevice, notificationCallback,
294 reinterpret_cast<void*>(listener) );
295 if (res != OK) {
296 ALOGE("%s: Unable to set notification callback!", __FUNCTION__);
297 }
298 return res;
299}
300
301void Camera2Device::notificationCallback(int32_t msg_type,
302 int32_t ext1,
303 int32_t ext2,
304 int32_t ext3,
305 void *user) {
306 NotificationListener *listener = reinterpret_cast<NotificationListener*>(user);
307 ALOGV("%s: Notification %d, arguments %d, %d, %d", __FUNCTION__, msg_type,
308 ext1, ext2, ext3);
309 if (listener != NULL) {
310 switch (msg_type) {
311 case CAMERA2_MSG_ERROR:
312 listener->notifyError(ext1, ext2, ext3);
313 break;
314 case CAMERA2_MSG_SHUTTER: {
315 nsecs_t timestamp = (nsecs_t)ext2 | ((nsecs_t)(ext3) << 32 );
316 listener->notifyShutter(ext1, timestamp);
317 break;
318 }
319 case CAMERA2_MSG_AUTOFOCUS:
320 listener->notifyAutoFocus(ext1, ext2);
321 break;
322 case CAMERA2_MSG_AUTOEXPOSURE:
323 listener->notifyAutoExposure(ext1, ext2);
324 break;
325 case CAMERA2_MSG_AUTOWB:
326 listener->notifyAutoWhitebalance(ext1, ext2);
327 break;
328 default:
329 ALOGE("%s: Unknown notification %d (arguments %d, %d, %d)!",
330 __FUNCTION__, msg_type, ext1, ext2, ext3);
331 }
332 }
333}
334
335/**
336 * Camera2Device::NotificationListener
337 */
338
339Camera2Device::NotificationListener::~NotificationListener() {
340}
341
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700342/**
343 * Camera2Device::MetadataQueue
344 */
345
346Camera2Device::MetadataQueue::MetadataQueue():
347 mDevice(NULL),
348 mFrameCount(0),
349 mCount(0),
350 mStreamSlotCount(0),
351 mSignalConsumer(true)
352{
353 camera2_request_queue_src_ops::dequeue_request = consumer_dequeue;
354 camera2_request_queue_src_ops::request_count = consumer_buffer_count;
355 camera2_request_queue_src_ops::free_request = consumer_free;
356
357 camera2_frame_queue_dst_ops::dequeue_frame = producer_dequeue;
358 camera2_frame_queue_dst_ops::cancel_frame = producer_cancel;
359 camera2_frame_queue_dst_ops::enqueue_frame = producer_enqueue;
360}
361
362Camera2Device::MetadataQueue::~MetadataQueue() {
363 Mutex::Autolock l(mMutex);
364 freeBuffers(mEntries.begin(), mEntries.end());
365 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
366}
367
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700368// Connect to camera2 HAL as consumer (input requests/reprocessing)
369status_t Camera2Device::MetadataQueue::setConsumerDevice(camera2_device_t *d) {
370 status_t res;
371 res = d->ops->set_request_queue_src_ops(d,
372 this);
373 if (res != OK) return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700374 mDevice = d;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700375 return OK;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700376}
377
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700378status_t Camera2Device::MetadataQueue::setProducerDevice(camera2_device_t *d) {
379 status_t res;
380 res = d->ops->set_frame_queue_dst_ops(d,
381 this);
382 return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700383}
384
385// Real interfaces
386status_t Camera2Device::MetadataQueue::enqueue(camera_metadata_t *buf) {
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700387 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700388 Mutex::Autolock l(mMutex);
389
390 mCount++;
391 mEntries.push_back(buf);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700392
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700393 return signalConsumerLocked();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700394}
395
396int Camera2Device::MetadataQueue::getBufferCount() {
397 Mutex::Autolock l(mMutex);
398 if (mStreamSlotCount > 0) {
399 return CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS;
400 }
401 return mCount;
402}
403
404status_t Camera2Device::MetadataQueue::dequeue(camera_metadata_t **buf,
405 bool incrementCount)
406{
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700407 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700408 status_t res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700409 Mutex::Autolock l(mMutex);
410
411 if (mCount == 0) {
412 if (mStreamSlotCount == 0) {
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700413 ALOGVV("%s: Empty", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700414 *buf = NULL;
415 mSignalConsumer = true;
416 return OK;
417 }
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700418 ALOGVV("%s: Streaming %d frames to queue", __FUNCTION__,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700419 mStreamSlotCount);
420
421 for (List<camera_metadata_t*>::iterator slotEntry = mStreamSlot.begin();
422 slotEntry != mStreamSlot.end();
423 slotEntry++ ) {
424 size_t entries = get_camera_metadata_entry_count(*slotEntry);
425 size_t dataBytes = get_camera_metadata_data_count(*slotEntry);
426
427 camera_metadata_t *copy =
428 allocate_camera_metadata(entries, dataBytes);
429 append_camera_metadata(copy, *slotEntry);
430 mEntries.push_back(copy);
431 }
432 mCount = mStreamSlotCount;
433 }
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700434 ALOGVV("MetadataQueue: deque (%d buffers)", mCount);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700435 camera_metadata_t *b = *(mEntries.begin());
436 mEntries.erase(mEntries.begin());
437
438 if (incrementCount) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700439 camera_metadata_entry_t frameCount;
440 res = find_camera_metadata_entry(b,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700441 ANDROID_REQUEST_FRAME_COUNT,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700442 &frameCount);
443 if (res != OK) {
444 ALOGE("%s: Unable to add frame count: %s (%d)",
445 __FUNCTION__, strerror(-res), res);
446 } else {
447 *frameCount.data.i32 = mFrameCount;
448 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700449 mFrameCount++;
450 }
451
452 *buf = b;
453 mCount--;
454
455 return OK;
456}
457
458status_t Camera2Device::MetadataQueue::waitForBuffer(nsecs_t timeout)
459{
460 Mutex::Autolock l(mMutex);
461 status_t res;
462 while (mCount == 0) {
463 res = notEmpty.waitRelative(mMutex,timeout);
464 if (res != OK) return res;
465 }
466 return OK;
467}
468
469status_t Camera2Device::MetadataQueue::setStreamSlot(camera_metadata_t *buf)
470{
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700471 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700472 Mutex::Autolock l(mMutex);
473 if (buf == NULL) {
474 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
475 mStreamSlotCount = 0;
476 return OK;
477 }
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700478 camera_metadata_t *buf2 = clone_camera_metadata(buf);
479 if (!buf2) {
480 ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__);
481 return NO_MEMORY;
482 }
483
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700484 if (mStreamSlotCount > 1) {
485 List<camera_metadata_t*>::iterator deleter = ++mStreamSlot.begin();
486 freeBuffers(++mStreamSlot.begin(), mStreamSlot.end());
487 mStreamSlotCount = 1;
488 }
489 if (mStreamSlotCount == 1) {
490 free_camera_metadata( *(mStreamSlot.begin()) );
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700491 *(mStreamSlot.begin()) = buf2;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700492 } else {
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700493 mStreamSlot.push_front(buf2);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700494 mStreamSlotCount = 1;
495 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700496 return signalConsumerLocked();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700497}
498
499status_t Camera2Device::MetadataQueue::setStreamSlot(
500 const List<camera_metadata_t*> &bufs)
501{
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700502 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700503 Mutex::Autolock l(mMutex);
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700504 status_t res;
505
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700506 if (mStreamSlotCount > 0) {
507 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
508 }
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700509 mStreamSlotCount = 0;
510 for (List<camera_metadata_t*>::const_iterator r = bufs.begin();
511 r != bufs.end(); r++) {
512 camera_metadata_t *r2 = clone_camera_metadata(*r);
513 if (!r2) {
514 ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__);
515 return NO_MEMORY;
516 }
517 mStreamSlot.push_back(r2);
518 mStreamSlotCount++;
519 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700520 return signalConsumerLocked();
521}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700522
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700523status_t Camera2Device::MetadataQueue::dump(int fd,
524 const Vector<String16>& args) {
525 String8 result;
526 status_t notLocked;
527 notLocked = mMutex.tryLock();
528 if (notLocked) {
529 result.append(" (Unable to lock queue mutex)\n");
530 }
531 result.appendFormat(" Current frame number: %d\n", mFrameCount);
532 if (mStreamSlotCount == 0) {
533 result.append(" Stream slot: Empty\n");
534 write(fd, result.string(), result.size());
535 } else {
536 result.appendFormat(" Stream slot: %d entries\n",
537 mStreamSlot.size());
538 int i = 0;
539 for (List<camera_metadata_t*>::iterator r = mStreamSlot.begin();
540 r != mStreamSlot.end(); r++) {
541 result = String8::format(" Stream slot buffer %d:\n", i);
542 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700543 dump_indented_camera_metadata(*r, fd, 2, 10);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700544 i++;
545 }
546 }
547 if (mEntries.size() == 0) {
548 result = " Main queue is empty\n";
549 write(fd, result.string(), result.size());
550 } else {
551 result = String8::format(" Main queue has %d entries:\n",
552 mEntries.size());
553 int i = 0;
554 for (List<camera_metadata_t*>::iterator r = mEntries.begin();
555 r != mEntries.end(); r++) {
556 result = String8::format(" Queue entry %d:\n", i);
557 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700558 dump_indented_camera_metadata(*r, fd, 2, 10);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700559 i++;
560 }
561 }
562
563 if (notLocked == 0) {
564 mMutex.unlock();
565 }
566
567 return OK;
568}
569
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700570status_t Camera2Device::MetadataQueue::signalConsumerLocked() {
571 status_t res = OK;
572 notEmpty.signal();
573 if (mSignalConsumer && mDevice != NULL) {
574 mSignalConsumer = false;
575
576 mMutex.unlock();
577 ALOGV("%s: Signaling consumer", __FUNCTION__);
578 res = mDevice->ops->notify_request_queue_not_empty(mDevice);
579 mMutex.lock();
580 }
581 return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700582}
583
584status_t Camera2Device::MetadataQueue::freeBuffers(
585 List<camera_metadata_t*>::iterator start,
586 List<camera_metadata_t*>::iterator end)
587{
588 while (start != end) {
589 free_camera_metadata(*start);
590 start = mStreamSlot.erase(start);
591 }
592 return OK;
593}
594
595Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
596 const camera2_request_queue_src_ops_t *q)
597{
598 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
599 return const_cast<MetadataQueue*>(cmq);
600}
601
602Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
603 const camera2_frame_queue_dst_ops_t *q)
604{
605 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
606 return const_cast<MetadataQueue*>(cmq);
607}
608
609int Camera2Device::MetadataQueue::consumer_buffer_count(
610 const camera2_request_queue_src_ops_t *q)
611{
612 MetadataQueue *queue = getInstance(q);
613 return queue->getBufferCount();
614}
615
616int Camera2Device::MetadataQueue::consumer_dequeue(
617 const camera2_request_queue_src_ops_t *q,
618 camera_metadata_t **buffer)
619{
620 MetadataQueue *queue = getInstance(q);
621 return queue->dequeue(buffer, true);
622}
623
624int Camera2Device::MetadataQueue::consumer_free(
625 const camera2_request_queue_src_ops_t *q,
626 camera_metadata_t *old_buffer)
627{
628 MetadataQueue *queue = getInstance(q);
629 free_camera_metadata(old_buffer);
630 return OK;
631}
632
633int Camera2Device::MetadataQueue::producer_dequeue(
634 const camera2_frame_queue_dst_ops_t *q,
635 size_t entries, size_t bytes,
636 camera_metadata_t **buffer)
637{
638 camera_metadata_t *new_buffer =
639 allocate_camera_metadata(entries, bytes);
640 if (new_buffer == NULL) return NO_MEMORY;
641 *buffer = new_buffer;
642 return OK;
643}
644
645int Camera2Device::MetadataQueue::producer_cancel(
646 const camera2_frame_queue_dst_ops_t *q,
647 camera_metadata_t *old_buffer)
648{
649 free_camera_metadata(old_buffer);
650 return OK;
651}
652
653int Camera2Device::MetadataQueue::producer_enqueue(
654 const camera2_frame_queue_dst_ops_t *q,
655 camera_metadata_t *filled_buffer)
656{
657 MetadataQueue *queue = getInstance(q);
658 return queue->enqueue(filled_buffer);
659}
660
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700661/**
662 * Camera2Device::StreamAdapter
663 */
664
665#ifndef container_of
666#define container_of(ptr, type, member) \
667 (type *)((char*)(ptr) - offsetof(type, member))
668#endif
669
670Camera2Device::StreamAdapter::StreamAdapter(camera2_device_t *d):
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700671 mState(RELEASED),
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700672 mDevice(d),
673 mId(-1),
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700674 mWidth(0), mHeight(0), mFormat(0), mSize(0), mUsage(0),
675 mMaxProducerBuffers(0), mMaxConsumerBuffers(0),
676 mTotalBuffers(0),
677 mFormatRequested(0),
678 mActiveBuffers(0),
679 mFrameCount(0),
680 mLastTimestamp(0)
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700681{
682 camera2_stream_ops::dequeue_buffer = dequeue_buffer;
683 camera2_stream_ops::enqueue_buffer = enqueue_buffer;
684 camera2_stream_ops::cancel_buffer = cancel_buffer;
685 camera2_stream_ops::set_crop = set_crop;
686}
687
688Camera2Device::StreamAdapter::~StreamAdapter() {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700689 if (mState != RELEASED) {
690 release();
691 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700692}
693
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700694status_t Camera2Device::StreamAdapter::connectToDevice(
695 sp<ANativeWindow> consumer,
696 uint32_t width, uint32_t height, int format, size_t size) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700697 status_t res;
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700698 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700699
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700700 if (mState != RELEASED) return INVALID_OPERATION;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700701 if (consumer == NULL) {
702 ALOGE("%s: Null consumer passed to stream adapter", __FUNCTION__);
703 return BAD_VALUE;
704 }
705
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700706 ALOGV("%s: New stream parameters %d x %d, format 0x%x, size %d",
707 __FUNCTION__, width, height, format, size);
708
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700709 mConsumerInterface = consumer;
710 mWidth = width;
711 mHeight = height;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700712 mSize = (format == HAL_PIXEL_FORMAT_BLOB) ? size : 0;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700713 mFormatRequested = format;
714
715 // Allocate device-side stream interface
716
717 uint32_t id;
718 uint32_t formatActual;
719 uint32_t usage;
720 uint32_t maxBuffers = 2;
721 res = mDevice->ops->allocate_stream(mDevice,
722 mWidth, mHeight, mFormatRequested, getStreamOps(),
723 &id, &formatActual, &usage, &maxBuffers);
724 if (res != OK) {
725 ALOGE("%s: Device stream allocation failed: %s (%d)",
726 __FUNCTION__, strerror(-res), res);
727 return res;
728 }
729
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700730 ALOGV("%s: Allocated stream id %d, actual format 0x%x, "
731 "usage 0x%x, producer wants %d buffers", __FUNCTION__,
732 id, formatActual, usage, maxBuffers);
733
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700734 mId = id;
735 mFormat = formatActual;
736 mUsage = usage;
737 mMaxProducerBuffers = maxBuffers;
738
739 mState = ALLOCATED;
740
741 // Configure consumer-side ANativeWindow interface
742 res = native_window_api_connect(mConsumerInterface.get(),
743 NATIVE_WINDOW_API_CAMERA);
744 if (res != OK) {
745 ALOGE("%s: Unable to connect to native window for stream %d",
746 __FUNCTION__, mId);
747
748 return res;
749 }
750
751 mState = CONNECTED;
752
753 res = native_window_set_usage(mConsumerInterface.get(), mUsage);
754 if (res != OK) {
755 ALOGE("%s: Unable to configure usage %08x for stream %d",
756 __FUNCTION__, mUsage, mId);
757 return res;
758 }
759
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -0700760 res = native_window_set_scaling_mode(mConsumerInterface.get(),
761 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
762 if (res != OK) {
763 ALOGE("%s: Unable to configure stream scaling: %s (%d)",
764 __FUNCTION__, strerror(-res), res);
765 return res;
766 }
767
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -0700768 res = setTransform(0);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -0700769 if (res != OK) {
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -0700770 return res;
771 }
772
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700773 if (mFormat == HAL_PIXEL_FORMAT_BLOB) {
774 res = native_window_set_buffers_geometry(mConsumerInterface.get(),
775 mSize, 1, mFormat);
776 if (res != OK) {
777 ALOGE("%s: Unable to configure compressed stream buffer geometry"
778 " %d x %d, size %d for stream %d",
779 __FUNCTION__, mWidth, mHeight, mSize, mId);
780 return res;
781 }
782 } else {
783 res = native_window_set_buffers_geometry(mConsumerInterface.get(),
784 mWidth, mHeight, mFormat);
785 if (res != OK) {
786 ALOGE("%s: Unable to configure stream buffer geometry"
787 " %d x %d, format 0x%x for stream %d",
788 __FUNCTION__, mWidth, mHeight, mFormat, mId);
789 return res;
790 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700791 }
792
793 int maxConsumerBuffers;
794 res = mConsumerInterface->query(mConsumerInterface.get(),
795 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &maxConsumerBuffers);
796 if (res != OK) {
797 ALOGE("%s: Unable to query consumer undequeued"
798 " buffer count for stream %d", __FUNCTION__, mId);
799 return res;
800 }
801 mMaxConsumerBuffers = maxConsumerBuffers;
802
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700803 ALOGV("%s: Consumer wants %d buffers", __FUNCTION__,
804 mMaxConsumerBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700805
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700806 mTotalBuffers = mMaxConsumerBuffers + mMaxProducerBuffers;
807 mActiveBuffers = 0;
808 mFrameCount = 0;
809 mLastTimestamp = 0;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700810
811 res = native_window_set_buffer_count(mConsumerInterface.get(),
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700812 mTotalBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700813 if (res != OK) {
814 ALOGE("%s: Unable to set buffer count for stream %d",
815 __FUNCTION__, mId);
816 return res;
817 }
818
819 // Register allocated buffers with HAL device
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700820 buffer_handle_t *buffers = new buffer_handle_t[mTotalBuffers];
821 ANativeWindowBuffer **anwBuffers = new ANativeWindowBuffer*[mTotalBuffers];
822 uint32_t bufferIdx = 0;
823 for (; bufferIdx < mTotalBuffers; bufferIdx++) {
Jamie Gennis1e5b2b32012-06-13 16:29:51 -0700824 res = native_window_dequeue_buffer_and_wait(mConsumerInterface.get(),
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700825 &anwBuffers[bufferIdx]);
826 if (res != OK) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700827 ALOGE("%s: Unable to dequeue buffer %d for initial registration for "
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700828 "stream %d", __FUNCTION__, bufferIdx, mId);
829 goto cleanUpBuffers;
830 }
831
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700832 buffers[bufferIdx] = anwBuffers[bufferIdx]->handle;
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -0700833 ALOGV("%s: Buffer %p allocated", __FUNCTION__, (void*)(buffers[bufferIdx]));
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700834 }
835
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -0700836 ALOGV("%s: Registering %d buffers with camera HAL", __FUNCTION__, mTotalBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700837 res = mDevice->ops->register_stream_buffers(mDevice,
838 mId,
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700839 mTotalBuffers,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700840 buffers);
841 if (res != OK) {
842 ALOGE("%s: Unable to register buffers with HAL device for stream %d",
843 __FUNCTION__, mId);
844 } else {
845 mState = ACTIVE;
846 }
847
848cleanUpBuffers:
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -0700849 ALOGV("%s: Cleaning up %d buffers", __FUNCTION__, bufferIdx);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700850 for (uint32_t i = 0; i < bufferIdx; i++) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700851 res = mConsumerInterface->cancelBuffer(mConsumerInterface.get(),
Jamie Gennis1e5b2b32012-06-13 16:29:51 -0700852 anwBuffers[i], -1);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700853 if (res != OK) {
854 ALOGE("%s: Unable to cancel buffer %d after registration",
855 __FUNCTION__, i);
856 }
857 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700858 delete[] anwBuffers;
859 delete[] buffers;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700860
861 return res;
862}
863
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700864status_t Camera2Device::StreamAdapter::release() {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700865 status_t res;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700866 ALOGV("%s: Releasing stream %d", __FUNCTION__, mId);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700867 if (mState >= ALLOCATED) {
868 res = mDevice->ops->release_stream(mDevice, mId);
869 if (res != OK) {
870 ALOGE("%s: Unable to release stream %d",
871 __FUNCTION__, mId);
872 return res;
873 }
874 }
875 if (mState >= CONNECTED) {
876 res = native_window_api_disconnect(mConsumerInterface.get(),
877 NATIVE_WINDOW_API_CAMERA);
878 if (res != OK) {
879 ALOGE("%s: Unable to disconnect stream %d from native window",
880 __FUNCTION__, mId);
881 return res;
882 }
883 }
884 mId = -1;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700885 mState = RELEASED;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700886 return OK;
887}
888
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -0700889status_t Camera2Device::StreamAdapter::setTransform(int transform) {
890 status_t res;
891 if (mState < CONNECTED) {
892 ALOGE("%s: Cannot set transform on unconnected stream", __FUNCTION__);
893 return INVALID_OPERATION;
894 }
895 res = native_window_set_buffers_transform(mConsumerInterface.get(),
896 transform);
897 if (res != OK) {
898 ALOGE("%s: Unable to configure stream transform to %x: %s (%d)",
899 __FUNCTION__, transform, strerror(-res), res);
900 }
901 return res;
902}
903
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700904status_t Camera2Device::StreamAdapter::dump(int fd,
905 const Vector<String16>& args) {
906 String8 result = String8::format(" Stream %d: %d x %d, format 0x%x\n",
907 mId, mWidth, mHeight, mFormat);
908 result.appendFormat(" size %d, usage 0x%x, requested format 0x%x\n",
909 mSize, mUsage, mFormatRequested);
910 result.appendFormat(" total buffers: %d, dequeued buffers: %d\n",
911 mTotalBuffers, mActiveBuffers);
912 result.appendFormat(" frame count: %d, last timestamp %lld\n",
913 mFrameCount, mLastTimestamp);
914 write(fd, result.string(), result.size());
915 return OK;
916}
917
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700918const camera2_stream_ops *Camera2Device::StreamAdapter::getStreamOps() {
919 return static_cast<camera2_stream_ops *>(this);
920}
921
922ANativeWindow* Camera2Device::StreamAdapter::toANW(
923 const camera2_stream_ops_t *w) {
924 return static_cast<const StreamAdapter*>(w)->mConsumerInterface.get();
925}
926
927int Camera2Device::StreamAdapter::dequeue_buffer(const camera2_stream_ops_t *w,
928 buffer_handle_t** buffer) {
929 int res;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700930 StreamAdapter* stream =
931 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
932 if (stream->mState != ACTIVE) {
933 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700934 return INVALID_OPERATION;
935 }
936
937 ANativeWindow *a = toANW(w);
938 ANativeWindowBuffer* anb;
Jamie Gennis1e5b2b32012-06-13 16:29:51 -0700939 res = native_window_dequeue_buffer_and_wait(a, &anb);
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -0700940 if (res != OK) {
941 ALOGE("Stream %d dequeue: Error from native_window: %s (%d)", stream->mId,
942 strerror(-res), res);
943 return res;
944 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700945
946 *buffer = &(anb->handle);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700947 stream->mActiveBuffers++;
948
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -0700949 ALOGVV("Stream %d dequeue: Buffer %p dequeued", stream->mId, (void*)(**buffer));
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700950 return res;
951}
952
953int Camera2Device::StreamAdapter::enqueue_buffer(const camera2_stream_ops_t* w,
954 int64_t timestamp,
955 buffer_handle_t* buffer) {
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700956 StreamAdapter *stream =
957 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -0700958 ALOGVV("Stream %d enqueue: Buffer %p captured at %lld ns",
959 stream->mId, (void*)(*buffer), timestamp);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -0700960 int state = stream->mState;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700961 if (state != ACTIVE) {
962 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
963 return INVALID_OPERATION;
964 }
965 ANativeWindow *a = toANW(w);
966 status_t err;
967 err = native_window_set_buffers_timestamp(a, timestamp);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -0700968 if (err != OK) {
969 ALOGE("%s: Error setting timestamp on native window: %s (%d)",
970 __FUNCTION__, strerror(-err), err);
971 return err;
972 }
973 err = a->queueBuffer(a,
Jamie Gennis1e5b2b32012-06-13 16:29:51 -0700974 container_of(buffer, ANativeWindowBuffer, handle), -1);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -0700975 if (err != OK) {
976 ALOGE("%s: Error queueing buffer to native window: %s (%d)",
977 __FUNCTION__, strerror(-err), err);
978 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700979 stream->mActiveBuffers--;
980 stream->mFrameCount++;
981 stream->mLastTimestamp = timestamp;
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -0700982 return err;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700983}
984
985int Camera2Device::StreamAdapter::cancel_buffer(const camera2_stream_ops_t* w,
986 buffer_handle_t* buffer) {
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700987 StreamAdapter *stream =
988 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -0700989 ALOGVV("Stream %d cancel: Buffer %p",
990 stream->mId, (void*)(*buffer));
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700991 if (stream->mState != ACTIVE) {
992 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700993 return INVALID_OPERATION;
994 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700995 stream->mActiveBuffers--;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700996 ANativeWindow *a = toANW(w);
997 return a->cancelBuffer(a,
Jamie Gennis1e5b2b32012-06-13 16:29:51 -0700998 container_of(buffer, ANativeWindowBuffer, handle), -1);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700999}
1000
1001int Camera2Device::StreamAdapter::set_crop(const camera2_stream_ops_t* w,
1002 int left, int top, int right, int bottom) {
1003 int state = static_cast<const StreamAdapter*>(w)->mState;
1004 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 android_native_rect_t crop = { left, top, right, bottom };
1010 return native_window_set_crop(a, &crop);
1011}
1012
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001013
1014}; // namespace android