blob: 35c4e74edc1340f000430f5eaeacadc4f5404e98 [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 Talvalac8474b62012-08-24 16:30:44 -070036 ALOGV("%s: Created device for camera %d", __FUNCTION__, id);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070037}
38
39Camera2Device::~Camera2Device()
40{
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -070041 ALOGV("%s: Shutting down device for camera %d", __FUNCTION__, mId);
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 }
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -070052 ALOGV("%s: Shutdown complete", __FUNCTION__);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070053}
54
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070055status_t Camera2Device::initialize(camera_module_t *module)
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070056{
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -070057 ALOGV("%s: Initializing device for camera %d", __FUNCTION__, mId);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -070058
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070059 status_t res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070060 char name[10];
61 snprintf(name, sizeof(name), "%d", mId);
62
63 res = module->common.methods->open(&module->common, name,
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070064 reinterpret_cast<hw_device_t**>(&mDevice));
65
66 if (res != OK) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070067 ALOGE("%s: Could not open camera %d: %s (%d)", __FUNCTION__,
68 mId, strerror(-res), res);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070069 return res;
70 }
71
72 if (mDevice->common.version != CAMERA_DEVICE_API_VERSION_2_0) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070073 ALOGE("%s: Could not open camera %d: "
74 "Camera device is not version %x, reports %x instead",
75 __FUNCTION__, mId, CAMERA_DEVICE_API_VERSION_2_0,
76 mDevice->common.version);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070077 return BAD_VALUE;
78 }
79
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070080 camera_info info;
81 res = module->get_camera_info(mId, &info);
82 if (res != OK ) return res;
83
84 if (info.device_version != mDevice->common.version) {
85 ALOGE("%s: HAL reporting mismatched camera_info version (%x)"
86 " and device version (%x).", __FUNCTION__,
87 mDevice->common.version, info.device_version);
88 return BAD_VALUE;
89 }
90
91 mDeviceInfo = info.static_camera_characteristics;
92
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -070093 res = mRequestQueue.setConsumerDevice(mDevice);
94 if (res != OK) {
95 ALOGE("%s: Camera %d: Unable to connect request queue to device: %s (%d)",
96 __FUNCTION__, mId, strerror(-res), res);
97 return res;
98 }
99 res = mFrameQueue.setProducerDevice(mDevice);
100 if (res != OK) {
101 ALOGE("%s: Camera %d: Unable to connect frame queue to device: %s (%d)",
102 __FUNCTION__, mId, strerror(-res), res);
103 return res;
104 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700105
106 res = mDevice->ops->get_metadata_vendor_tag_ops(mDevice, &mVendorTagOps);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700107 if (res != OK ) {
108 ALOGE("%s: Camera %d: Unable to retrieve tag ops from device: %s (%d)",
109 __FUNCTION__, mId, strerror(-res), res);
110 return res;
111 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700112
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700113 setNotifyCallback(NULL);
114
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700115 return OK;
116}
117
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700118status_t Camera2Device::dump(int fd, const Vector<String16>& args) {
119
120 String8 result;
Eino-Ville Talvala97197152012-08-06 14:25:19 -0700121 int detailLevel = 0;
122 int n = args.size();
123 String16 detailOption("-d");
124 for (int i = 0; i + 1 < n; i++) {
125 if (args[i] == detailOption) {
126 String8 levelStr(args[i+1]);
127 detailLevel = atoi(levelStr.string());
128 }
129 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700130
Eino-Ville Talvala603b12e2012-08-08 09:25:58 -0700131 result.appendFormat(" Camera2Device[%d] dump (detail level %d):\n",
132 mId, detailLevel);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700133
Eino-Ville Talvala97197152012-08-06 14:25:19 -0700134 if (detailLevel > 0) {
135 result = " Request queue contents:\n";
136 write(fd, result.string(), result.size());
137 mRequestQueue.dump(fd, args);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700138
Eino-Ville Talvala97197152012-08-06 14:25:19 -0700139 result = " Frame queue contents:\n";
140 write(fd, result.string(), result.size());
141 mFrameQueue.dump(fd, args);
142 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700143
144 result = " Active streams:\n";
145 write(fd, result.string(), result.size());
146 for (StreamList::iterator s = mStreams.begin(); s != mStreams.end(); s++) {
147 (*s)->dump(fd, args);
148 }
149
150 result = " HAL device dump:\n";
151 write(fd, result.string(), result.size());
152
153 status_t res;
154 res = mDevice->ops->dump(mDevice, fd);
155
156 return res;
157}
158
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700159const CameraMetadata& Camera2Device::info() const {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700160 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700161
162 return mDeviceInfo;
163}
164
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700165status_t Camera2Device::capture(CameraMetadata &request) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700166 ALOGV("%s: E", __FUNCTION__);
167
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700168 mRequestQueue.enqueue(request.release());
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700169 return OK;
170}
171
172
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700173status_t Camera2Device::setStreamingRequest(const CameraMetadata &request) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700174 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700175 CameraMetadata streamRequest(request);
176 return mRequestQueue.setStreamSlot(streamRequest.release());
177}
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700178
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700179status_t Camera2Device::clearStreamingRequest() {
180 return mRequestQueue.setStreamSlot(NULL);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700181}
182
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700183status_t Camera2Device::createStream(sp<ANativeWindow> consumer,
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700184 uint32_t width, uint32_t height, int format, size_t size, int *id) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700185 status_t res;
186 ALOGV("%s: E", __FUNCTION__);
187
188 sp<StreamAdapter> stream = new StreamAdapter(mDevice);
189
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700190 res = stream->connectToDevice(consumer, width, height, format, size);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700191 if (res != OK) {
192 ALOGE("%s: Camera %d: Unable to create stream (%d x %d, format %x):"
193 "%s (%d)",
194 __FUNCTION__, mId, width, height, format, strerror(-res), res);
195 return res;
196 }
197
198 *id = stream->getId();
199
200 mStreams.push_back(stream);
201 return OK;
202}
203
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700204status_t Camera2Device::getStreamInfo(int id,
205 uint32_t *width, uint32_t *height, uint32_t *format) {
206 ALOGV("%s: E", __FUNCTION__);
207 bool found = false;
208 StreamList::iterator streamI;
209 for (streamI = mStreams.begin();
210 streamI != mStreams.end(); streamI++) {
211 if ((*streamI)->getId() == id) {
212 found = true;
213 break;
214 }
215 }
216 if (!found) {
217 ALOGE("%s: Camera %d: Stream %d does not exist",
218 __FUNCTION__, mId, id);
219 return BAD_VALUE;
220 }
221
222 if (width) *width = (*streamI)->getWidth();
223 if (height) *height = (*streamI)->getHeight();
224 if (format) *format = (*streamI)->getFormat();
225
226 return OK;
227}
228
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -0700229status_t Camera2Device::setStreamTransform(int id,
230 int transform) {
231 ALOGV("%s: E", __FUNCTION__);
232 bool found = false;
233 StreamList::iterator streamI;
234 for (streamI = mStreams.begin();
235 streamI != mStreams.end(); streamI++) {
236 if ((*streamI)->getId() == id) {
237 found = true;
238 break;
239 }
240 }
241 if (!found) {
242 ALOGE("%s: Camera %d: Stream %d does not exist",
243 __FUNCTION__, mId, id);
244 return BAD_VALUE;
245 }
246
247 return (*streamI)->setTransform(transform);
248}
249
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700250status_t Camera2Device::deleteStream(int id) {
251 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700252 bool found = false;
253 for (StreamList::iterator streamI = mStreams.begin();
254 streamI != mStreams.end(); streamI++) {
255 if ((*streamI)->getId() == id) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700256 status_t res = (*streamI)->release();
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700257 if (res != OK) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700258 ALOGE("%s: Unable to release stream %d from HAL device: "
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700259 "%s (%d)", __FUNCTION__, id, strerror(-res), res);
260 return res;
261 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700262 mStreams.erase(streamI);
263 found = true;
264 break;
265 }
266 }
267 if (!found) {
268 ALOGE("%s: Camera %d: Unable to find stream %d to delete",
269 __FUNCTION__, mId, id);
270 return BAD_VALUE;
271 }
272 return OK;
273}
274
275status_t Camera2Device::createDefaultRequest(int templateId,
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700276 CameraMetadata *request) {
277 status_t err;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700278 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700279 camera_metadata_t *rawRequest;
280 err = mDevice->ops->construct_default_request(
281 mDevice, templateId, &rawRequest);
282 request->acquire(rawRequest);
283 return err;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700284}
285
286status_t Camera2Device::waitUntilDrained() {
287 static const uint32_t kSleepTime = 50000; // 50 ms
288 static const uint32_t kMaxSleepTime = 10000000; // 10 s
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700289 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700290 if (mRequestQueue.getBufferCount() ==
291 CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS) return INVALID_OPERATION;
292
293 // TODO: Set up notifications from HAL, instead of sleeping here
294 uint32_t totalTime = 0;
295 while (mDevice->ops->get_in_progress_count(mDevice) > 0) {
296 usleep(kSleepTime);
297 totalTime += kSleepTime;
298 if (totalTime > kMaxSleepTime) {
299 ALOGE("%s: Waited %d us, requests still in flight", __FUNCTION__,
300 totalTime);
301 return TIMED_OUT;
302 }
303 }
304 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700305}
306
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700307status_t Camera2Device::setNotifyCallback(NotificationListener *listener) {
308 status_t res;
309 res = mDevice->ops->set_notify_callback(mDevice, notificationCallback,
310 reinterpret_cast<void*>(listener) );
311 if (res != OK) {
312 ALOGE("%s: Unable to set notification callback!", __FUNCTION__);
313 }
314 return res;
315}
316
317void Camera2Device::notificationCallback(int32_t msg_type,
318 int32_t ext1,
319 int32_t ext2,
320 int32_t ext3,
321 void *user) {
322 NotificationListener *listener = reinterpret_cast<NotificationListener*>(user);
323 ALOGV("%s: Notification %d, arguments %d, %d, %d", __FUNCTION__, msg_type,
324 ext1, ext2, ext3);
325 if (listener != NULL) {
326 switch (msg_type) {
327 case CAMERA2_MSG_ERROR:
328 listener->notifyError(ext1, ext2, ext3);
329 break;
330 case CAMERA2_MSG_SHUTTER: {
331 nsecs_t timestamp = (nsecs_t)ext2 | ((nsecs_t)(ext3) << 32 );
332 listener->notifyShutter(ext1, timestamp);
333 break;
334 }
335 case CAMERA2_MSG_AUTOFOCUS:
336 listener->notifyAutoFocus(ext1, ext2);
337 break;
338 case CAMERA2_MSG_AUTOEXPOSURE:
339 listener->notifyAutoExposure(ext1, ext2);
340 break;
341 case CAMERA2_MSG_AUTOWB:
342 listener->notifyAutoWhitebalance(ext1, ext2);
343 break;
344 default:
345 ALOGE("%s: Unknown notification %d (arguments %d, %d, %d)!",
346 __FUNCTION__, msg_type, ext1, ext2, ext3);
347 }
348 }
349}
350
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -0700351status_t Camera2Device::waitForNextFrame(nsecs_t timeout) {
352 return mFrameQueue.waitForBuffer(timeout);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700353}
354
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700355status_t Camera2Device::getNextFrame(CameraMetadata *frame) {
356 status_t res;
357 camera_metadata_t *rawFrame;
358 res = mFrameQueue.dequeue(&rawFrame);
359 if (rawFrame == NULL) {
360 return NOT_ENOUGH_DATA;
361 } else if (res == OK) {
362 frame->acquire(rawFrame);
363 }
364 return res;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700365}
366
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700367status_t Camera2Device::triggerAutofocus(uint32_t id) {
368 status_t res;
369 ALOGV("%s: Triggering autofocus, id %d", __FUNCTION__, id);
370 res = mDevice->ops->trigger_action(mDevice,
371 CAMERA2_TRIGGER_AUTOFOCUS, id, 0);
372 if (res != OK) {
373 ALOGE("%s: Error triggering autofocus (id %d)",
374 __FUNCTION__, id);
375 }
376 return res;
377}
378
379status_t Camera2Device::triggerCancelAutofocus(uint32_t id) {
380 status_t res;
381 ALOGV("%s: Canceling autofocus, id %d", __FUNCTION__, id);
382 res = mDevice->ops->trigger_action(mDevice,
383 CAMERA2_TRIGGER_CANCEL_AUTOFOCUS, id, 0);
384 if (res != OK) {
385 ALOGE("%s: Error canceling autofocus (id %d)",
386 __FUNCTION__, id);
387 }
388 return res;
389}
390
391status_t Camera2Device::triggerPrecaptureMetering(uint32_t id) {
392 status_t res;
393 ALOGV("%s: Triggering precapture metering, id %d", __FUNCTION__, id);
394 res = mDevice->ops->trigger_action(mDevice,
395 CAMERA2_TRIGGER_PRECAPTURE_METERING, id, 0);
396 if (res != OK) {
397 ALOGE("%s: Error triggering precapture metering (id %d)",
398 __FUNCTION__, id);
399 }
400 return res;
401}
402
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700403/**
404 * Camera2Device::NotificationListener
405 */
406
407Camera2Device::NotificationListener::~NotificationListener() {
408}
409
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700410/**
411 * Camera2Device::MetadataQueue
412 */
413
414Camera2Device::MetadataQueue::MetadataQueue():
415 mDevice(NULL),
416 mFrameCount(0),
417 mCount(0),
418 mStreamSlotCount(0),
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -0700419 mSignalConsumer(true)
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700420{
421 camera2_request_queue_src_ops::dequeue_request = consumer_dequeue;
422 camera2_request_queue_src_ops::request_count = consumer_buffer_count;
423 camera2_request_queue_src_ops::free_request = consumer_free;
424
425 camera2_frame_queue_dst_ops::dequeue_frame = producer_dequeue;
426 camera2_frame_queue_dst_ops::cancel_frame = producer_cancel;
427 camera2_frame_queue_dst_ops::enqueue_frame = producer_enqueue;
428}
429
430Camera2Device::MetadataQueue::~MetadataQueue() {
431 Mutex::Autolock l(mMutex);
432 freeBuffers(mEntries.begin(), mEntries.end());
433 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
434}
435
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700436// Connect to camera2 HAL as consumer (input requests/reprocessing)
437status_t Camera2Device::MetadataQueue::setConsumerDevice(camera2_device_t *d) {
438 status_t res;
439 res = d->ops->set_request_queue_src_ops(d,
440 this);
441 if (res != OK) return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700442 mDevice = d;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700443 return OK;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700444}
445
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700446status_t Camera2Device::MetadataQueue::setProducerDevice(camera2_device_t *d) {
447 status_t res;
448 res = d->ops->set_frame_queue_dst_ops(d,
449 this);
450 return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700451}
452
453// Real interfaces
454status_t Camera2Device::MetadataQueue::enqueue(camera_metadata_t *buf) {
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700455 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700456 Mutex::Autolock l(mMutex);
457
458 mCount++;
459 mEntries.push_back(buf);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700460
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700461 return signalConsumerLocked();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700462}
463
464int Camera2Device::MetadataQueue::getBufferCount() {
465 Mutex::Autolock l(mMutex);
466 if (mStreamSlotCount > 0) {
467 return CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS;
468 }
469 return mCount;
470}
471
472status_t Camera2Device::MetadataQueue::dequeue(camera_metadata_t **buf,
473 bool incrementCount)
474{
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700475 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700476 status_t res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700477 Mutex::Autolock l(mMutex);
478
479 if (mCount == 0) {
480 if (mStreamSlotCount == 0) {
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700481 ALOGVV("%s: Empty", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700482 *buf = NULL;
483 mSignalConsumer = true;
484 return OK;
485 }
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700486 ALOGVV("%s: Streaming %d frames to queue", __FUNCTION__,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700487 mStreamSlotCount);
488
489 for (List<camera_metadata_t*>::iterator slotEntry = mStreamSlot.begin();
490 slotEntry != mStreamSlot.end();
491 slotEntry++ ) {
492 size_t entries = get_camera_metadata_entry_count(*slotEntry);
493 size_t dataBytes = get_camera_metadata_data_count(*slotEntry);
494
495 camera_metadata_t *copy =
496 allocate_camera_metadata(entries, dataBytes);
497 append_camera_metadata(copy, *slotEntry);
498 mEntries.push_back(copy);
499 }
500 mCount = mStreamSlotCount;
501 }
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700502 ALOGVV("MetadataQueue: deque (%d buffers)", mCount);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700503 camera_metadata_t *b = *(mEntries.begin());
504 mEntries.erase(mEntries.begin());
505
506 if (incrementCount) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700507 camera_metadata_entry_t frameCount;
508 res = find_camera_metadata_entry(b,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700509 ANDROID_REQUEST_FRAME_COUNT,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700510 &frameCount);
511 if (res != OK) {
512 ALOGE("%s: Unable to add frame count: %s (%d)",
513 __FUNCTION__, strerror(-res), res);
514 } else {
515 *frameCount.data.i32 = mFrameCount;
516 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700517 mFrameCount++;
518 }
519
520 *buf = b;
521 mCount--;
522
523 return OK;
524}
525
526status_t Camera2Device::MetadataQueue::waitForBuffer(nsecs_t timeout)
527{
528 Mutex::Autolock l(mMutex);
529 status_t res;
530 while (mCount == 0) {
531 res = notEmpty.waitRelative(mMutex,timeout);
532 if (res != OK) return res;
533 }
534 return OK;
535}
536
537status_t Camera2Device::MetadataQueue::setStreamSlot(camera_metadata_t *buf)
538{
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700539 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700540 Mutex::Autolock l(mMutex);
541 if (buf == NULL) {
542 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
543 mStreamSlotCount = 0;
544 return OK;
545 }
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700546 camera_metadata_t *buf2 = clone_camera_metadata(buf);
547 if (!buf2) {
548 ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__);
549 return NO_MEMORY;
550 }
551
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700552 if (mStreamSlotCount > 1) {
553 List<camera_metadata_t*>::iterator deleter = ++mStreamSlot.begin();
554 freeBuffers(++mStreamSlot.begin(), mStreamSlot.end());
555 mStreamSlotCount = 1;
556 }
557 if (mStreamSlotCount == 1) {
558 free_camera_metadata( *(mStreamSlot.begin()) );
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700559 *(mStreamSlot.begin()) = buf2;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700560 } else {
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700561 mStreamSlot.push_front(buf2);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700562 mStreamSlotCount = 1;
563 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700564 return signalConsumerLocked();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700565}
566
567status_t Camera2Device::MetadataQueue::setStreamSlot(
568 const List<camera_metadata_t*> &bufs)
569{
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700570 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700571 Mutex::Autolock l(mMutex);
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700572 status_t res;
573
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700574 if (mStreamSlotCount > 0) {
575 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
576 }
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700577 mStreamSlotCount = 0;
578 for (List<camera_metadata_t*>::const_iterator r = bufs.begin();
579 r != bufs.end(); r++) {
580 camera_metadata_t *r2 = clone_camera_metadata(*r);
581 if (!r2) {
582 ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__);
583 return NO_MEMORY;
584 }
585 mStreamSlot.push_back(r2);
586 mStreamSlotCount++;
587 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700588 return signalConsumerLocked();
589}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700590
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700591status_t Camera2Device::MetadataQueue::dump(int fd,
592 const Vector<String16>& args) {
593 String8 result;
594 status_t notLocked;
595 notLocked = mMutex.tryLock();
596 if (notLocked) {
597 result.append(" (Unable to lock queue mutex)\n");
598 }
599 result.appendFormat(" Current frame number: %d\n", mFrameCount);
600 if (mStreamSlotCount == 0) {
601 result.append(" Stream slot: Empty\n");
602 write(fd, result.string(), result.size());
603 } else {
604 result.appendFormat(" Stream slot: %d entries\n",
605 mStreamSlot.size());
606 int i = 0;
607 for (List<camera_metadata_t*>::iterator r = mStreamSlot.begin();
608 r != mStreamSlot.end(); r++) {
609 result = String8::format(" Stream slot buffer %d:\n", i);
610 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700611 dump_indented_camera_metadata(*r, fd, 2, 10);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700612 i++;
613 }
614 }
615 if (mEntries.size() == 0) {
616 result = " Main queue is empty\n";
617 write(fd, result.string(), result.size());
618 } else {
619 result = String8::format(" Main queue has %d entries:\n",
620 mEntries.size());
621 int i = 0;
622 for (List<camera_metadata_t*>::iterator r = mEntries.begin();
623 r != mEntries.end(); r++) {
624 result = String8::format(" Queue entry %d:\n", i);
625 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700626 dump_indented_camera_metadata(*r, fd, 2, 10);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700627 i++;
628 }
629 }
630
631 if (notLocked == 0) {
632 mMutex.unlock();
633 }
634
635 return OK;
636}
637
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700638status_t Camera2Device::MetadataQueue::signalConsumerLocked() {
639 status_t res = OK;
640 notEmpty.signal();
641 if (mSignalConsumer && mDevice != NULL) {
642 mSignalConsumer = false;
643
644 mMutex.unlock();
645 ALOGV("%s: Signaling consumer", __FUNCTION__);
646 res = mDevice->ops->notify_request_queue_not_empty(mDevice);
647 mMutex.lock();
648 }
649 return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700650}
651
652status_t Camera2Device::MetadataQueue::freeBuffers(
653 List<camera_metadata_t*>::iterator start,
654 List<camera_metadata_t*>::iterator end)
655{
656 while (start != end) {
657 free_camera_metadata(*start);
658 start = mStreamSlot.erase(start);
659 }
660 return OK;
661}
662
663Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
664 const camera2_request_queue_src_ops_t *q)
665{
666 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
667 return const_cast<MetadataQueue*>(cmq);
668}
669
670Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
671 const camera2_frame_queue_dst_ops_t *q)
672{
673 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
674 return const_cast<MetadataQueue*>(cmq);
675}
676
677int Camera2Device::MetadataQueue::consumer_buffer_count(
678 const camera2_request_queue_src_ops_t *q)
679{
680 MetadataQueue *queue = getInstance(q);
681 return queue->getBufferCount();
682}
683
684int Camera2Device::MetadataQueue::consumer_dequeue(
685 const camera2_request_queue_src_ops_t *q,
686 camera_metadata_t **buffer)
687{
688 MetadataQueue *queue = getInstance(q);
689 return queue->dequeue(buffer, true);
690}
691
692int Camera2Device::MetadataQueue::consumer_free(
693 const camera2_request_queue_src_ops_t *q,
694 camera_metadata_t *old_buffer)
695{
696 MetadataQueue *queue = getInstance(q);
697 free_camera_metadata(old_buffer);
698 return OK;
699}
700
701int Camera2Device::MetadataQueue::producer_dequeue(
702 const camera2_frame_queue_dst_ops_t *q,
703 size_t entries, size_t bytes,
704 camera_metadata_t **buffer)
705{
706 camera_metadata_t *new_buffer =
707 allocate_camera_metadata(entries, bytes);
708 if (new_buffer == NULL) return NO_MEMORY;
709 *buffer = new_buffer;
710 return OK;
711}
712
713int Camera2Device::MetadataQueue::producer_cancel(
714 const camera2_frame_queue_dst_ops_t *q,
715 camera_metadata_t *old_buffer)
716{
717 free_camera_metadata(old_buffer);
718 return OK;
719}
720
721int Camera2Device::MetadataQueue::producer_enqueue(
722 const camera2_frame_queue_dst_ops_t *q,
723 camera_metadata_t *filled_buffer)
724{
725 MetadataQueue *queue = getInstance(q);
726 return queue->enqueue(filled_buffer);
727}
728
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700729/**
730 * Camera2Device::StreamAdapter
731 */
732
733#ifndef container_of
734#define container_of(ptr, type, member) \
735 (type *)((char*)(ptr) - offsetof(type, member))
736#endif
737
738Camera2Device::StreamAdapter::StreamAdapter(camera2_device_t *d):
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700739 mState(RELEASED),
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700740 mDevice(d),
741 mId(-1),
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700742 mWidth(0), mHeight(0), mFormat(0), mSize(0), mUsage(0),
743 mMaxProducerBuffers(0), mMaxConsumerBuffers(0),
744 mTotalBuffers(0),
745 mFormatRequested(0),
746 mActiveBuffers(0),
747 mFrameCount(0),
748 mLastTimestamp(0)
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700749{
750 camera2_stream_ops::dequeue_buffer = dequeue_buffer;
751 camera2_stream_ops::enqueue_buffer = enqueue_buffer;
752 camera2_stream_ops::cancel_buffer = cancel_buffer;
753 camera2_stream_ops::set_crop = set_crop;
754}
755
756Camera2Device::StreamAdapter::~StreamAdapter() {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700757 if (mState != RELEASED) {
758 release();
759 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700760}
761
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700762status_t Camera2Device::StreamAdapter::connectToDevice(
763 sp<ANativeWindow> consumer,
764 uint32_t width, uint32_t height, int format, size_t size) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700765 status_t res;
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700766 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700767
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700768 if (mState != RELEASED) return INVALID_OPERATION;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700769 if (consumer == NULL) {
770 ALOGE("%s: Null consumer passed to stream adapter", __FUNCTION__);
771 return BAD_VALUE;
772 }
773
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700774 ALOGV("%s: New stream parameters %d x %d, format 0x%x, size %d",
775 __FUNCTION__, width, height, format, size);
776
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700777 mConsumerInterface = consumer;
778 mWidth = width;
779 mHeight = height;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700780 mSize = (format == HAL_PIXEL_FORMAT_BLOB) ? size : 0;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700781 mFormatRequested = format;
782
783 // Allocate device-side stream interface
784
785 uint32_t id;
786 uint32_t formatActual;
787 uint32_t usage;
788 uint32_t maxBuffers = 2;
789 res = mDevice->ops->allocate_stream(mDevice,
790 mWidth, mHeight, mFormatRequested, getStreamOps(),
791 &id, &formatActual, &usage, &maxBuffers);
792 if (res != OK) {
793 ALOGE("%s: Device stream allocation failed: %s (%d)",
794 __FUNCTION__, strerror(-res), res);
795 return res;
796 }
797
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700798 ALOGV("%s: Allocated stream id %d, actual format 0x%x, "
799 "usage 0x%x, producer wants %d buffers", __FUNCTION__,
800 id, formatActual, usage, maxBuffers);
801
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700802 mId = id;
803 mFormat = formatActual;
804 mUsage = usage;
805 mMaxProducerBuffers = maxBuffers;
806
807 mState = ALLOCATED;
808
809 // Configure consumer-side ANativeWindow interface
810 res = native_window_api_connect(mConsumerInterface.get(),
811 NATIVE_WINDOW_API_CAMERA);
812 if (res != OK) {
813 ALOGE("%s: Unable to connect to native window for stream %d",
814 __FUNCTION__, mId);
815
816 return res;
817 }
818
819 mState = CONNECTED;
820
821 res = native_window_set_usage(mConsumerInterface.get(), mUsage);
822 if (res != OK) {
823 ALOGE("%s: Unable to configure usage %08x for stream %d",
824 __FUNCTION__, mUsage, mId);
825 return res;
826 }
827
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -0700828 res = native_window_set_scaling_mode(mConsumerInterface.get(),
829 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
830 if (res != OK) {
831 ALOGE("%s: Unable to configure stream scaling: %s (%d)",
832 __FUNCTION__, strerror(-res), res);
833 return res;
834 }
835
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -0700836 res = setTransform(0);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -0700837 if (res != OK) {
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -0700838 return res;
839 }
840
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700841 if (mFormat == HAL_PIXEL_FORMAT_BLOB) {
842 res = native_window_set_buffers_geometry(mConsumerInterface.get(),
843 mSize, 1, mFormat);
844 if (res != OK) {
845 ALOGE("%s: Unable to configure compressed stream buffer geometry"
846 " %d x %d, size %d for stream %d",
847 __FUNCTION__, mWidth, mHeight, mSize, mId);
848 return res;
849 }
850 } else {
851 res = native_window_set_buffers_geometry(mConsumerInterface.get(),
852 mWidth, mHeight, mFormat);
853 if (res != OK) {
854 ALOGE("%s: Unable to configure stream buffer geometry"
855 " %d x %d, format 0x%x for stream %d",
856 __FUNCTION__, mWidth, mHeight, mFormat, mId);
857 return res;
858 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700859 }
860
861 int maxConsumerBuffers;
862 res = mConsumerInterface->query(mConsumerInterface.get(),
863 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &maxConsumerBuffers);
864 if (res != OK) {
865 ALOGE("%s: Unable to query consumer undequeued"
866 " buffer count for stream %d", __FUNCTION__, mId);
867 return res;
868 }
869 mMaxConsumerBuffers = maxConsumerBuffers;
870
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700871 ALOGV("%s: Consumer wants %d buffers", __FUNCTION__,
872 mMaxConsumerBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700873
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700874 mTotalBuffers = mMaxConsumerBuffers + mMaxProducerBuffers;
875 mActiveBuffers = 0;
876 mFrameCount = 0;
877 mLastTimestamp = 0;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700878
879 res = native_window_set_buffer_count(mConsumerInterface.get(),
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700880 mTotalBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700881 if (res != OK) {
882 ALOGE("%s: Unable to set buffer count for stream %d",
883 __FUNCTION__, mId);
884 return res;
885 }
886
887 // Register allocated buffers with HAL device
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700888 buffer_handle_t *buffers = new buffer_handle_t[mTotalBuffers];
889 ANativeWindowBuffer **anwBuffers = new ANativeWindowBuffer*[mTotalBuffers];
890 uint32_t bufferIdx = 0;
891 for (; bufferIdx < mTotalBuffers; bufferIdx++) {
Jamie Gennis1e5b2b32012-06-13 16:29:51 -0700892 res = native_window_dequeue_buffer_and_wait(mConsumerInterface.get(),
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700893 &anwBuffers[bufferIdx]);
894 if (res != OK) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700895 ALOGE("%s: Unable to dequeue buffer %d for initial registration for "
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700896 "stream %d", __FUNCTION__, bufferIdx, mId);
897 goto cleanUpBuffers;
898 }
899
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700900 buffers[bufferIdx] = anwBuffers[bufferIdx]->handle;
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -0700901 ALOGV("%s: Buffer %p allocated", __FUNCTION__, (void*)(buffers[bufferIdx]));
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700902 }
903
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -0700904 ALOGV("%s: Registering %d buffers with camera HAL", __FUNCTION__, mTotalBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700905 res = mDevice->ops->register_stream_buffers(mDevice,
906 mId,
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700907 mTotalBuffers,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700908 buffers);
909 if (res != OK) {
910 ALOGE("%s: Unable to register buffers with HAL device for stream %d",
911 __FUNCTION__, mId);
912 } else {
913 mState = ACTIVE;
914 }
915
916cleanUpBuffers:
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -0700917 ALOGV("%s: Cleaning up %d buffers", __FUNCTION__, bufferIdx);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700918 for (uint32_t i = 0; i < bufferIdx; i++) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700919 res = mConsumerInterface->cancelBuffer(mConsumerInterface.get(),
Jamie Gennis1e5b2b32012-06-13 16:29:51 -0700920 anwBuffers[i], -1);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700921 if (res != OK) {
922 ALOGE("%s: Unable to cancel buffer %d after registration",
923 __FUNCTION__, i);
924 }
925 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700926 delete[] anwBuffers;
927 delete[] buffers;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700928
929 return res;
930}
931
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700932status_t Camera2Device::StreamAdapter::release() {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700933 status_t res;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700934 ALOGV("%s: Releasing stream %d", __FUNCTION__, mId);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700935 if (mState >= ALLOCATED) {
936 res = mDevice->ops->release_stream(mDevice, mId);
937 if (res != OK) {
938 ALOGE("%s: Unable to release stream %d",
939 __FUNCTION__, mId);
940 return res;
941 }
942 }
943 if (mState >= CONNECTED) {
944 res = native_window_api_disconnect(mConsumerInterface.get(),
945 NATIVE_WINDOW_API_CAMERA);
946 if (res != OK) {
947 ALOGE("%s: Unable to disconnect stream %d from native window",
948 __FUNCTION__, mId);
949 return res;
950 }
951 }
952 mId = -1;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700953 mState = RELEASED;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700954 return OK;
955}
956
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -0700957status_t Camera2Device::StreamAdapter::setTransform(int transform) {
958 status_t res;
959 if (mState < CONNECTED) {
960 ALOGE("%s: Cannot set transform on unconnected stream", __FUNCTION__);
961 return INVALID_OPERATION;
962 }
963 res = native_window_set_buffers_transform(mConsumerInterface.get(),
964 transform);
965 if (res != OK) {
966 ALOGE("%s: Unable to configure stream transform to %x: %s (%d)",
967 __FUNCTION__, transform, strerror(-res), res);
968 }
969 return res;
970}
971
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700972status_t Camera2Device::StreamAdapter::dump(int fd,
973 const Vector<String16>& args) {
974 String8 result = String8::format(" Stream %d: %d x %d, format 0x%x\n",
975 mId, mWidth, mHeight, mFormat);
976 result.appendFormat(" size %d, usage 0x%x, requested format 0x%x\n",
977 mSize, mUsage, mFormatRequested);
978 result.appendFormat(" total buffers: %d, dequeued buffers: %d\n",
979 mTotalBuffers, mActiveBuffers);
980 result.appendFormat(" frame count: %d, last timestamp %lld\n",
981 mFrameCount, mLastTimestamp);
982 write(fd, result.string(), result.size());
983 return OK;
984}
985
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700986const camera2_stream_ops *Camera2Device::StreamAdapter::getStreamOps() {
987 return static_cast<camera2_stream_ops *>(this);
988}
989
990ANativeWindow* Camera2Device::StreamAdapter::toANW(
991 const camera2_stream_ops_t *w) {
992 return static_cast<const StreamAdapter*>(w)->mConsumerInterface.get();
993}
994
995int Camera2Device::StreamAdapter::dequeue_buffer(const camera2_stream_ops_t *w,
996 buffer_handle_t** buffer) {
997 int res;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700998 StreamAdapter* stream =
999 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
1000 if (stream->mState != ACTIVE) {
1001 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001002 return INVALID_OPERATION;
1003 }
1004
1005 ANativeWindow *a = toANW(w);
1006 ANativeWindowBuffer* anb;
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001007 res = native_window_dequeue_buffer_and_wait(a, &anb);
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001008 if (res != OK) {
1009 ALOGE("Stream %d dequeue: Error from native_window: %s (%d)", stream->mId,
1010 strerror(-res), res);
1011 return res;
1012 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001013
1014 *buffer = &(anb->handle);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001015 stream->mActiveBuffers++;
1016
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001017 ALOGVV("Stream %d dequeue: Buffer %p dequeued", stream->mId, (void*)(**buffer));
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001018 return res;
1019}
1020
1021int Camera2Device::StreamAdapter::enqueue_buffer(const camera2_stream_ops_t* w,
1022 int64_t timestamp,
1023 buffer_handle_t* buffer) {
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001024 StreamAdapter *stream =
1025 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001026 stream->mFrameCount++;
1027 ALOGVV("Stream %d enqueue: Frame %d (%p) captured at %lld ns",
1028 stream->mId, mFrameCount, (void*)(*buffer), timestamp);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001029 int state = stream->mState;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001030 if (state != ACTIVE) {
1031 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1032 return INVALID_OPERATION;
1033 }
1034 ANativeWindow *a = toANW(w);
1035 status_t err;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001036
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001037 err = native_window_set_buffers_timestamp(a, timestamp);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001038 if (err != OK) {
1039 ALOGE("%s: Error setting timestamp on native window: %s (%d)",
1040 __FUNCTION__, strerror(-err), err);
1041 return err;
1042 }
1043 err = a->queueBuffer(a,
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001044 container_of(buffer, ANativeWindowBuffer, handle), -1);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001045 if (err != OK) {
1046 ALOGE("%s: Error queueing buffer to native window: %s (%d)",
1047 __FUNCTION__, strerror(-err), err);
James Dong31d377b2012-08-09 17:43:46 -07001048 return err;
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001049 }
James Dong31d377b2012-08-09 17:43:46 -07001050
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001051 stream->mActiveBuffers--;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001052 stream->mLastTimestamp = timestamp;
James Dong31d377b2012-08-09 17:43:46 -07001053 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001054}
1055
1056int Camera2Device::StreamAdapter::cancel_buffer(const camera2_stream_ops_t* w,
1057 buffer_handle_t* buffer) {
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001058 StreamAdapter *stream =
1059 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001060 ALOGVV("Stream %d cancel: Buffer %p",
1061 stream->mId, (void*)(*buffer));
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001062 if (stream->mState != ACTIVE) {
1063 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001064 return INVALID_OPERATION;
1065 }
James Dong31d377b2012-08-09 17:43:46 -07001066
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001067 ANativeWindow *a = toANW(w);
James Dong31d377b2012-08-09 17:43:46 -07001068 int err = a->cancelBuffer(a,
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001069 container_of(buffer, ANativeWindowBuffer, handle), -1);
James Dong31d377b2012-08-09 17:43:46 -07001070 if (err != OK) {
1071 ALOGE("%s: Error canceling buffer to native window: %s (%d)",
1072 __FUNCTION__, strerror(-err), err);
1073 return err;
1074 }
1075
1076 stream->mActiveBuffers--;
1077 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001078}
1079
1080int Camera2Device::StreamAdapter::set_crop(const camera2_stream_ops_t* w,
1081 int left, int top, int right, int bottom) {
1082 int state = static_cast<const StreamAdapter*>(w)->mState;
1083 if (state != ACTIVE) {
1084 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1085 return INVALID_OPERATION;
1086 }
1087 ANativeWindow *a = toANW(w);
1088 android_native_rect_t crop = { left, top, right, bottom };
1089 return native_window_set_crop(a, &crop);
1090}
1091
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001092
1093}; // namespace android