blob: daeeebbdf3a661bfbb4b4ca9b1f94070657c2b14 [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 }
Shuzhen Wang092fe442012-08-31 10:24:22 -0700112 res = set_camera_metadata_vendor_tag_ops(mVendorTagOps);
113 if (res != OK) {
114 ALOGE("%s: Camera %d: Unable to set tag ops: %s (%d)",
115 __FUNCTION__, mId, strerror(-res), res);
116 return res;
117 }
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700118 setNotifyCallback(NULL);
119
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700120 return OK;
121}
122
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700123status_t Camera2Device::dump(int fd, const Vector<String16>& args) {
124
125 String8 result;
Eino-Ville Talvala97197152012-08-06 14:25:19 -0700126 int detailLevel = 0;
127 int n = args.size();
128 String16 detailOption("-d");
129 for (int i = 0; i + 1 < n; i++) {
130 if (args[i] == detailOption) {
131 String8 levelStr(args[i+1]);
132 detailLevel = atoi(levelStr.string());
133 }
134 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700135
Eino-Ville Talvala603b12e2012-08-08 09:25:58 -0700136 result.appendFormat(" Camera2Device[%d] dump (detail level %d):\n",
137 mId, detailLevel);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700138
Eino-Ville Talvala97197152012-08-06 14:25:19 -0700139 if (detailLevel > 0) {
140 result = " Request queue contents:\n";
141 write(fd, result.string(), result.size());
142 mRequestQueue.dump(fd, args);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700143
Eino-Ville Talvala97197152012-08-06 14:25:19 -0700144 result = " Frame queue contents:\n";
145 write(fd, result.string(), result.size());
146 mFrameQueue.dump(fd, args);
147 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700148
149 result = " Active streams:\n";
150 write(fd, result.string(), result.size());
151 for (StreamList::iterator s = mStreams.begin(); s != mStreams.end(); s++) {
152 (*s)->dump(fd, args);
153 }
154
155 result = " HAL device dump:\n";
156 write(fd, result.string(), result.size());
157
158 status_t res;
159 res = mDevice->ops->dump(mDevice, fd);
160
161 return res;
162}
163
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700164const camera2::CameraMetadata& Camera2Device::info() const {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700165 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700166
167 return mDeviceInfo;
168}
169
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700170status_t Camera2Device::capture(CameraMetadata &request) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700171 ALOGV("%s: E", __FUNCTION__);
172
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700173 mRequestQueue.enqueue(request.release());
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700174 return OK;
175}
176
177
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700178status_t Camera2Device::setStreamingRequest(const CameraMetadata &request) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700179 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700180 CameraMetadata streamRequest(request);
181 return mRequestQueue.setStreamSlot(streamRequest.release());
182}
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700183
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700184status_t Camera2Device::clearStreamingRequest() {
185 return mRequestQueue.setStreamSlot(NULL);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700186}
187
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700188status_t Camera2Device::createStream(sp<ANativeWindow> consumer,
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700189 uint32_t width, uint32_t height, int format, size_t size, int *id) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700190 status_t res;
191 ALOGV("%s: E", __FUNCTION__);
192
193 sp<StreamAdapter> stream = new StreamAdapter(mDevice);
194
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700195 res = stream->connectToDevice(consumer, width, height, format, size);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700196 if (res != OK) {
197 ALOGE("%s: Camera %d: Unable to create stream (%d x %d, format %x):"
198 "%s (%d)",
199 __FUNCTION__, mId, width, height, format, strerror(-res), res);
200 return res;
201 }
202
203 *id = stream->getId();
204
205 mStreams.push_back(stream);
206 return OK;
207}
208
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700209status_t Camera2Device::getStreamInfo(int id,
210 uint32_t *width, uint32_t *height, uint32_t *format) {
211 ALOGV("%s: E", __FUNCTION__);
212 bool found = false;
213 StreamList::iterator streamI;
214 for (streamI = mStreams.begin();
215 streamI != mStreams.end(); streamI++) {
216 if ((*streamI)->getId() == id) {
217 found = true;
218 break;
219 }
220 }
221 if (!found) {
222 ALOGE("%s: Camera %d: Stream %d does not exist",
223 __FUNCTION__, mId, id);
224 return BAD_VALUE;
225 }
226
227 if (width) *width = (*streamI)->getWidth();
228 if (height) *height = (*streamI)->getHeight();
229 if (format) *format = (*streamI)->getFormat();
230
231 return OK;
232}
233
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -0700234status_t Camera2Device::setStreamTransform(int id,
235 int transform) {
236 ALOGV("%s: E", __FUNCTION__);
237 bool found = false;
238 StreamList::iterator streamI;
239 for (streamI = mStreams.begin();
240 streamI != mStreams.end(); streamI++) {
241 if ((*streamI)->getId() == id) {
242 found = true;
243 break;
244 }
245 }
246 if (!found) {
247 ALOGE("%s: Camera %d: Stream %d does not exist",
248 __FUNCTION__, mId, id);
249 return BAD_VALUE;
250 }
251
252 return (*streamI)->setTransform(transform);
253}
254
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700255status_t Camera2Device::deleteStream(int id) {
256 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700257 bool found = false;
258 for (StreamList::iterator streamI = mStreams.begin();
259 streamI != mStreams.end(); streamI++) {
260 if ((*streamI)->getId() == id) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700261 status_t res = (*streamI)->release();
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700262 if (res != OK) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700263 ALOGE("%s: Unable to release stream %d from HAL device: "
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700264 "%s (%d)", __FUNCTION__, id, strerror(-res), res);
265 return res;
266 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700267 mStreams.erase(streamI);
268 found = true;
269 break;
270 }
271 }
272 if (!found) {
273 ALOGE("%s: Camera %d: Unable to find stream %d to delete",
274 __FUNCTION__, mId, id);
275 return BAD_VALUE;
276 }
277 return OK;
278}
279
280status_t Camera2Device::createDefaultRequest(int templateId,
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700281 CameraMetadata *request) {
282 status_t err;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700283 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700284 camera_metadata_t *rawRequest;
285 err = mDevice->ops->construct_default_request(
286 mDevice, templateId, &rawRequest);
287 request->acquire(rawRequest);
288 return err;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700289}
290
291status_t Camera2Device::waitUntilDrained() {
292 static const uint32_t kSleepTime = 50000; // 50 ms
293 static const uint32_t kMaxSleepTime = 10000000; // 10 s
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700294 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700295 if (mRequestQueue.getBufferCount() ==
296 CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS) return INVALID_OPERATION;
297
298 // TODO: Set up notifications from HAL, instead of sleeping here
299 uint32_t totalTime = 0;
300 while (mDevice->ops->get_in_progress_count(mDevice) > 0) {
301 usleep(kSleepTime);
302 totalTime += kSleepTime;
303 if (totalTime > kMaxSleepTime) {
304 ALOGE("%s: Waited %d us, requests still in flight", __FUNCTION__,
305 totalTime);
306 return TIMED_OUT;
307 }
308 }
309 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700310}
311
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700312status_t Camera2Device::setNotifyCallback(NotificationListener *listener) {
313 status_t res;
314 res = mDevice->ops->set_notify_callback(mDevice, notificationCallback,
315 reinterpret_cast<void*>(listener) );
316 if (res != OK) {
317 ALOGE("%s: Unable to set notification callback!", __FUNCTION__);
318 }
319 return res;
320}
321
322void Camera2Device::notificationCallback(int32_t msg_type,
323 int32_t ext1,
324 int32_t ext2,
325 int32_t ext3,
326 void *user) {
327 NotificationListener *listener = reinterpret_cast<NotificationListener*>(user);
328 ALOGV("%s: Notification %d, arguments %d, %d, %d", __FUNCTION__, msg_type,
329 ext1, ext2, ext3);
330 if (listener != NULL) {
331 switch (msg_type) {
332 case CAMERA2_MSG_ERROR:
333 listener->notifyError(ext1, ext2, ext3);
334 break;
335 case CAMERA2_MSG_SHUTTER: {
336 nsecs_t timestamp = (nsecs_t)ext2 | ((nsecs_t)(ext3) << 32 );
337 listener->notifyShutter(ext1, timestamp);
338 break;
339 }
340 case CAMERA2_MSG_AUTOFOCUS:
341 listener->notifyAutoFocus(ext1, ext2);
342 break;
343 case CAMERA2_MSG_AUTOEXPOSURE:
344 listener->notifyAutoExposure(ext1, ext2);
345 break;
346 case CAMERA2_MSG_AUTOWB:
347 listener->notifyAutoWhitebalance(ext1, ext2);
348 break;
349 default:
350 ALOGE("%s: Unknown notification %d (arguments %d, %d, %d)!",
351 __FUNCTION__, msg_type, ext1, ext2, ext3);
352 }
353 }
354}
355
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -0700356status_t Camera2Device::waitForNextFrame(nsecs_t timeout) {
357 return mFrameQueue.waitForBuffer(timeout);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700358}
359
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700360status_t Camera2Device::getNextFrame(CameraMetadata *frame) {
361 status_t res;
362 camera_metadata_t *rawFrame;
363 res = mFrameQueue.dequeue(&rawFrame);
364 if (rawFrame == NULL) {
365 return NOT_ENOUGH_DATA;
366 } else if (res == OK) {
367 frame->acquire(rawFrame);
368 }
369 return res;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700370}
371
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700372status_t Camera2Device::triggerAutofocus(uint32_t id) {
373 status_t res;
374 ALOGV("%s: Triggering autofocus, id %d", __FUNCTION__, id);
375 res = mDevice->ops->trigger_action(mDevice,
376 CAMERA2_TRIGGER_AUTOFOCUS, id, 0);
377 if (res != OK) {
378 ALOGE("%s: Error triggering autofocus (id %d)",
379 __FUNCTION__, id);
380 }
381 return res;
382}
383
384status_t Camera2Device::triggerCancelAutofocus(uint32_t id) {
385 status_t res;
386 ALOGV("%s: Canceling autofocus, id %d", __FUNCTION__, id);
387 res = mDevice->ops->trigger_action(mDevice,
388 CAMERA2_TRIGGER_CANCEL_AUTOFOCUS, id, 0);
389 if (res != OK) {
390 ALOGE("%s: Error canceling autofocus (id %d)",
391 __FUNCTION__, id);
392 }
393 return res;
394}
395
396status_t Camera2Device::triggerPrecaptureMetering(uint32_t id) {
397 status_t res;
398 ALOGV("%s: Triggering precapture metering, id %d", __FUNCTION__, id);
399 res = mDevice->ops->trigger_action(mDevice,
400 CAMERA2_TRIGGER_PRECAPTURE_METERING, id, 0);
401 if (res != OK) {
402 ALOGE("%s: Error triggering precapture metering (id %d)",
403 __FUNCTION__, id);
404 }
405 return res;
406}
407
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700408/**
409 * Camera2Device::NotificationListener
410 */
411
412Camera2Device::NotificationListener::~NotificationListener() {
413}
414
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700415/**
416 * Camera2Device::MetadataQueue
417 */
418
419Camera2Device::MetadataQueue::MetadataQueue():
420 mDevice(NULL),
421 mFrameCount(0),
422 mCount(0),
423 mStreamSlotCount(0),
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -0700424 mSignalConsumer(true)
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700425{
426 camera2_request_queue_src_ops::dequeue_request = consumer_dequeue;
427 camera2_request_queue_src_ops::request_count = consumer_buffer_count;
428 camera2_request_queue_src_ops::free_request = consumer_free;
429
430 camera2_frame_queue_dst_ops::dequeue_frame = producer_dequeue;
431 camera2_frame_queue_dst_ops::cancel_frame = producer_cancel;
432 camera2_frame_queue_dst_ops::enqueue_frame = producer_enqueue;
433}
434
435Camera2Device::MetadataQueue::~MetadataQueue() {
436 Mutex::Autolock l(mMutex);
437 freeBuffers(mEntries.begin(), mEntries.end());
438 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
439}
440
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700441// Connect to camera2 HAL as consumer (input requests/reprocessing)
442status_t Camera2Device::MetadataQueue::setConsumerDevice(camera2_device_t *d) {
443 status_t res;
444 res = d->ops->set_request_queue_src_ops(d,
445 this);
446 if (res != OK) return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700447 mDevice = d;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700448 return OK;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700449}
450
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700451status_t Camera2Device::MetadataQueue::setProducerDevice(camera2_device_t *d) {
452 status_t res;
453 res = d->ops->set_frame_queue_dst_ops(d,
454 this);
455 return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700456}
457
458// Real interfaces
459status_t Camera2Device::MetadataQueue::enqueue(camera_metadata_t *buf) {
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700460 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700461 Mutex::Autolock l(mMutex);
462
463 mCount++;
464 mEntries.push_back(buf);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700465
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700466 return signalConsumerLocked();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700467}
468
469int Camera2Device::MetadataQueue::getBufferCount() {
470 Mutex::Autolock l(mMutex);
471 if (mStreamSlotCount > 0) {
472 return CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS;
473 }
474 return mCount;
475}
476
477status_t Camera2Device::MetadataQueue::dequeue(camera_metadata_t **buf,
478 bool incrementCount)
479{
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700480 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700481 status_t res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700482 Mutex::Autolock l(mMutex);
483
484 if (mCount == 0) {
485 if (mStreamSlotCount == 0) {
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700486 ALOGVV("%s: Empty", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700487 *buf = NULL;
488 mSignalConsumer = true;
489 return OK;
490 }
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700491 ALOGVV("%s: Streaming %d frames to queue", __FUNCTION__,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700492 mStreamSlotCount);
493
494 for (List<camera_metadata_t*>::iterator slotEntry = mStreamSlot.begin();
495 slotEntry != mStreamSlot.end();
496 slotEntry++ ) {
497 size_t entries = get_camera_metadata_entry_count(*slotEntry);
498 size_t dataBytes = get_camera_metadata_data_count(*slotEntry);
499
500 camera_metadata_t *copy =
501 allocate_camera_metadata(entries, dataBytes);
502 append_camera_metadata(copy, *slotEntry);
503 mEntries.push_back(copy);
504 }
505 mCount = mStreamSlotCount;
506 }
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700507 ALOGVV("MetadataQueue: deque (%d buffers)", mCount);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700508 camera_metadata_t *b = *(mEntries.begin());
509 mEntries.erase(mEntries.begin());
510
511 if (incrementCount) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700512 camera_metadata_entry_t frameCount;
513 res = find_camera_metadata_entry(b,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700514 ANDROID_REQUEST_FRAME_COUNT,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700515 &frameCount);
516 if (res != OK) {
517 ALOGE("%s: Unable to add frame count: %s (%d)",
518 __FUNCTION__, strerror(-res), res);
519 } else {
520 *frameCount.data.i32 = mFrameCount;
521 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700522 mFrameCount++;
523 }
524
525 *buf = b;
526 mCount--;
527
528 return OK;
529}
530
531status_t Camera2Device::MetadataQueue::waitForBuffer(nsecs_t timeout)
532{
533 Mutex::Autolock l(mMutex);
534 status_t res;
535 while (mCount == 0) {
536 res = notEmpty.waitRelative(mMutex,timeout);
537 if (res != OK) return res;
538 }
539 return OK;
540}
541
542status_t Camera2Device::MetadataQueue::setStreamSlot(camera_metadata_t *buf)
543{
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700544 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700545 Mutex::Autolock l(mMutex);
546 if (buf == NULL) {
547 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
548 mStreamSlotCount = 0;
549 return OK;
550 }
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700551 camera_metadata_t *buf2 = clone_camera_metadata(buf);
552 if (!buf2) {
553 ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__);
554 return NO_MEMORY;
555 }
556
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700557 if (mStreamSlotCount > 1) {
558 List<camera_metadata_t*>::iterator deleter = ++mStreamSlot.begin();
559 freeBuffers(++mStreamSlot.begin(), mStreamSlot.end());
560 mStreamSlotCount = 1;
561 }
562 if (mStreamSlotCount == 1) {
563 free_camera_metadata( *(mStreamSlot.begin()) );
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700564 *(mStreamSlot.begin()) = buf2;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700565 } else {
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700566 mStreamSlot.push_front(buf2);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700567 mStreamSlotCount = 1;
568 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700569 return signalConsumerLocked();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700570}
571
572status_t Camera2Device::MetadataQueue::setStreamSlot(
573 const List<camera_metadata_t*> &bufs)
574{
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700575 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700576 Mutex::Autolock l(mMutex);
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700577 status_t res;
578
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700579 if (mStreamSlotCount > 0) {
580 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
581 }
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700582 mStreamSlotCount = 0;
583 for (List<camera_metadata_t*>::const_iterator r = bufs.begin();
584 r != bufs.end(); r++) {
585 camera_metadata_t *r2 = clone_camera_metadata(*r);
586 if (!r2) {
587 ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__);
588 return NO_MEMORY;
589 }
590 mStreamSlot.push_back(r2);
591 mStreamSlotCount++;
592 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700593 return signalConsumerLocked();
594}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700595
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700596status_t Camera2Device::MetadataQueue::dump(int fd,
597 const Vector<String16>& args) {
598 String8 result;
599 status_t notLocked;
600 notLocked = mMutex.tryLock();
601 if (notLocked) {
602 result.append(" (Unable to lock queue mutex)\n");
603 }
604 result.appendFormat(" Current frame number: %d\n", mFrameCount);
605 if (mStreamSlotCount == 0) {
606 result.append(" Stream slot: Empty\n");
607 write(fd, result.string(), result.size());
608 } else {
609 result.appendFormat(" Stream slot: %d entries\n",
610 mStreamSlot.size());
611 int i = 0;
612 for (List<camera_metadata_t*>::iterator r = mStreamSlot.begin();
613 r != mStreamSlot.end(); r++) {
614 result = String8::format(" Stream slot buffer %d:\n", i);
615 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700616 dump_indented_camera_metadata(*r, fd, 2, 10);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700617 i++;
618 }
619 }
620 if (mEntries.size() == 0) {
621 result = " Main queue is empty\n";
622 write(fd, result.string(), result.size());
623 } else {
624 result = String8::format(" Main queue has %d entries:\n",
625 mEntries.size());
626 int i = 0;
627 for (List<camera_metadata_t*>::iterator r = mEntries.begin();
628 r != mEntries.end(); r++) {
629 result = String8::format(" Queue entry %d:\n", i);
630 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700631 dump_indented_camera_metadata(*r, fd, 2, 10);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700632 i++;
633 }
634 }
635
636 if (notLocked == 0) {
637 mMutex.unlock();
638 }
639
640 return OK;
641}
642
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700643status_t Camera2Device::MetadataQueue::signalConsumerLocked() {
644 status_t res = OK;
645 notEmpty.signal();
646 if (mSignalConsumer && mDevice != NULL) {
647 mSignalConsumer = false;
648
649 mMutex.unlock();
650 ALOGV("%s: Signaling consumer", __FUNCTION__);
651 res = mDevice->ops->notify_request_queue_not_empty(mDevice);
652 mMutex.lock();
653 }
654 return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700655}
656
657status_t Camera2Device::MetadataQueue::freeBuffers(
658 List<camera_metadata_t*>::iterator start,
659 List<camera_metadata_t*>::iterator end)
660{
661 while (start != end) {
662 free_camera_metadata(*start);
663 start = mStreamSlot.erase(start);
664 }
665 return OK;
666}
667
668Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
669 const camera2_request_queue_src_ops_t *q)
670{
671 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
672 return const_cast<MetadataQueue*>(cmq);
673}
674
675Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
676 const camera2_frame_queue_dst_ops_t *q)
677{
678 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
679 return const_cast<MetadataQueue*>(cmq);
680}
681
682int Camera2Device::MetadataQueue::consumer_buffer_count(
683 const camera2_request_queue_src_ops_t *q)
684{
685 MetadataQueue *queue = getInstance(q);
686 return queue->getBufferCount();
687}
688
689int Camera2Device::MetadataQueue::consumer_dequeue(
690 const camera2_request_queue_src_ops_t *q,
691 camera_metadata_t **buffer)
692{
693 MetadataQueue *queue = getInstance(q);
694 return queue->dequeue(buffer, true);
695}
696
697int Camera2Device::MetadataQueue::consumer_free(
698 const camera2_request_queue_src_ops_t *q,
699 camera_metadata_t *old_buffer)
700{
701 MetadataQueue *queue = getInstance(q);
702 free_camera_metadata(old_buffer);
703 return OK;
704}
705
706int Camera2Device::MetadataQueue::producer_dequeue(
707 const camera2_frame_queue_dst_ops_t *q,
708 size_t entries, size_t bytes,
709 camera_metadata_t **buffer)
710{
711 camera_metadata_t *new_buffer =
712 allocate_camera_metadata(entries, bytes);
713 if (new_buffer == NULL) return NO_MEMORY;
714 *buffer = new_buffer;
715 return OK;
716}
717
718int Camera2Device::MetadataQueue::producer_cancel(
719 const camera2_frame_queue_dst_ops_t *q,
720 camera_metadata_t *old_buffer)
721{
722 free_camera_metadata(old_buffer);
723 return OK;
724}
725
726int Camera2Device::MetadataQueue::producer_enqueue(
727 const camera2_frame_queue_dst_ops_t *q,
728 camera_metadata_t *filled_buffer)
729{
730 MetadataQueue *queue = getInstance(q);
731 return queue->enqueue(filled_buffer);
732}
733
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700734/**
735 * Camera2Device::StreamAdapter
736 */
737
738#ifndef container_of
739#define container_of(ptr, type, member) \
740 (type *)((char*)(ptr) - offsetof(type, member))
741#endif
742
743Camera2Device::StreamAdapter::StreamAdapter(camera2_device_t *d):
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700744 mState(RELEASED),
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700745 mDevice(d),
746 mId(-1),
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700747 mWidth(0), mHeight(0), mFormat(0), mSize(0), mUsage(0),
748 mMaxProducerBuffers(0), mMaxConsumerBuffers(0),
749 mTotalBuffers(0),
750 mFormatRequested(0),
751 mActiveBuffers(0),
752 mFrameCount(0),
753 mLastTimestamp(0)
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700754{
755 camera2_stream_ops::dequeue_buffer = dequeue_buffer;
756 camera2_stream_ops::enqueue_buffer = enqueue_buffer;
757 camera2_stream_ops::cancel_buffer = cancel_buffer;
758 camera2_stream_ops::set_crop = set_crop;
759}
760
761Camera2Device::StreamAdapter::~StreamAdapter() {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700762 if (mState != RELEASED) {
763 release();
764 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700765}
766
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700767status_t Camera2Device::StreamAdapter::connectToDevice(
768 sp<ANativeWindow> consumer,
769 uint32_t width, uint32_t height, int format, size_t size) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700770 status_t res;
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700771 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700772
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700773 if (mState != RELEASED) return INVALID_OPERATION;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700774 if (consumer == NULL) {
775 ALOGE("%s: Null consumer passed to stream adapter", __FUNCTION__);
776 return BAD_VALUE;
777 }
778
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700779 ALOGV("%s: New stream parameters %d x %d, format 0x%x, size %d",
780 __FUNCTION__, width, height, format, size);
781
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700782 mConsumerInterface = consumer;
783 mWidth = width;
784 mHeight = height;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700785 mSize = (format == HAL_PIXEL_FORMAT_BLOB) ? size : 0;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700786 mFormatRequested = format;
787
788 // Allocate device-side stream interface
789
790 uint32_t id;
791 uint32_t formatActual;
792 uint32_t usage;
793 uint32_t maxBuffers = 2;
794 res = mDevice->ops->allocate_stream(mDevice,
795 mWidth, mHeight, mFormatRequested, getStreamOps(),
796 &id, &formatActual, &usage, &maxBuffers);
797 if (res != OK) {
798 ALOGE("%s: Device stream allocation failed: %s (%d)",
799 __FUNCTION__, strerror(-res), res);
800 return res;
801 }
802
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700803 ALOGV("%s: Allocated stream id %d, actual format 0x%x, "
804 "usage 0x%x, producer wants %d buffers", __FUNCTION__,
805 id, formatActual, usage, maxBuffers);
806
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700807 mId = id;
808 mFormat = formatActual;
809 mUsage = usage;
810 mMaxProducerBuffers = maxBuffers;
811
812 mState = ALLOCATED;
813
814 // Configure consumer-side ANativeWindow interface
815 res = native_window_api_connect(mConsumerInterface.get(),
816 NATIVE_WINDOW_API_CAMERA);
817 if (res != OK) {
818 ALOGE("%s: Unable to connect to native window for stream %d",
819 __FUNCTION__, mId);
820
821 return res;
822 }
823
824 mState = CONNECTED;
825
826 res = native_window_set_usage(mConsumerInterface.get(), mUsage);
827 if (res != OK) {
828 ALOGE("%s: Unable to configure usage %08x for stream %d",
829 __FUNCTION__, mUsage, mId);
830 return res;
831 }
832
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -0700833 res = native_window_set_scaling_mode(mConsumerInterface.get(),
834 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
835 if (res != OK) {
836 ALOGE("%s: Unable to configure stream scaling: %s (%d)",
837 __FUNCTION__, strerror(-res), res);
838 return res;
839 }
840
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -0700841 res = setTransform(0);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -0700842 if (res != OK) {
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -0700843 return res;
844 }
845
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700846 if (mFormat == HAL_PIXEL_FORMAT_BLOB) {
847 res = native_window_set_buffers_geometry(mConsumerInterface.get(),
848 mSize, 1, mFormat);
849 if (res != OK) {
850 ALOGE("%s: Unable to configure compressed stream buffer geometry"
851 " %d x %d, size %d for stream %d",
852 __FUNCTION__, mWidth, mHeight, mSize, mId);
853 return res;
854 }
855 } else {
856 res = native_window_set_buffers_geometry(mConsumerInterface.get(),
857 mWidth, mHeight, mFormat);
858 if (res != OK) {
859 ALOGE("%s: Unable to configure stream buffer geometry"
860 " %d x %d, format 0x%x for stream %d",
861 __FUNCTION__, mWidth, mHeight, mFormat, mId);
862 return res;
863 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700864 }
865
866 int maxConsumerBuffers;
867 res = mConsumerInterface->query(mConsumerInterface.get(),
868 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &maxConsumerBuffers);
869 if (res != OK) {
870 ALOGE("%s: Unable to query consumer undequeued"
871 " buffer count for stream %d", __FUNCTION__, mId);
872 return res;
873 }
874 mMaxConsumerBuffers = maxConsumerBuffers;
875
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700876 ALOGV("%s: Consumer wants %d buffers", __FUNCTION__,
877 mMaxConsumerBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700878
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700879 mTotalBuffers = mMaxConsumerBuffers + mMaxProducerBuffers;
880 mActiveBuffers = 0;
881 mFrameCount = 0;
882 mLastTimestamp = 0;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700883
884 res = native_window_set_buffer_count(mConsumerInterface.get(),
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700885 mTotalBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700886 if (res != OK) {
887 ALOGE("%s: Unable to set buffer count for stream %d",
888 __FUNCTION__, mId);
889 return res;
890 }
891
892 // Register allocated buffers with HAL device
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700893 buffer_handle_t *buffers = new buffer_handle_t[mTotalBuffers];
894 ANativeWindowBuffer **anwBuffers = new ANativeWindowBuffer*[mTotalBuffers];
895 uint32_t bufferIdx = 0;
896 for (; bufferIdx < mTotalBuffers; bufferIdx++) {
Jamie Gennis1e5b2b32012-06-13 16:29:51 -0700897 res = native_window_dequeue_buffer_and_wait(mConsumerInterface.get(),
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700898 &anwBuffers[bufferIdx]);
899 if (res != OK) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700900 ALOGE("%s: Unable to dequeue buffer %d for initial registration for "
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700901 "stream %d", __FUNCTION__, bufferIdx, mId);
902 goto cleanUpBuffers;
903 }
904
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700905 buffers[bufferIdx] = anwBuffers[bufferIdx]->handle;
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -0700906 ALOGV("%s: Buffer %p allocated", __FUNCTION__, (void*)(buffers[bufferIdx]));
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700907 }
908
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -0700909 ALOGV("%s: Registering %d buffers with camera HAL", __FUNCTION__, mTotalBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700910 res = mDevice->ops->register_stream_buffers(mDevice,
911 mId,
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700912 mTotalBuffers,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700913 buffers);
914 if (res != OK) {
915 ALOGE("%s: Unable to register buffers with HAL device for stream %d",
916 __FUNCTION__, mId);
917 } else {
918 mState = ACTIVE;
919 }
920
921cleanUpBuffers:
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -0700922 ALOGV("%s: Cleaning up %d buffers", __FUNCTION__, bufferIdx);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700923 for (uint32_t i = 0; i < bufferIdx; i++) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700924 res = mConsumerInterface->cancelBuffer(mConsumerInterface.get(),
Jamie Gennis1e5b2b32012-06-13 16:29:51 -0700925 anwBuffers[i], -1);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700926 if (res != OK) {
927 ALOGE("%s: Unable to cancel buffer %d after registration",
928 __FUNCTION__, i);
929 }
930 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700931 delete[] anwBuffers;
932 delete[] buffers;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700933
934 return res;
935}
936
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700937status_t Camera2Device::StreamAdapter::release() {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700938 status_t res;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700939 ALOGV("%s: Releasing stream %d", __FUNCTION__, mId);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700940 if (mState >= ALLOCATED) {
941 res = mDevice->ops->release_stream(mDevice, mId);
942 if (res != OK) {
943 ALOGE("%s: Unable to release stream %d",
944 __FUNCTION__, mId);
945 return res;
946 }
947 }
948 if (mState >= CONNECTED) {
949 res = native_window_api_disconnect(mConsumerInterface.get(),
950 NATIVE_WINDOW_API_CAMERA);
951 if (res != OK) {
952 ALOGE("%s: Unable to disconnect stream %d from native window",
953 __FUNCTION__, mId);
954 return res;
955 }
956 }
957 mId = -1;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700958 mState = RELEASED;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700959 return OK;
960}
961
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -0700962status_t Camera2Device::StreamAdapter::setTransform(int transform) {
963 status_t res;
964 if (mState < CONNECTED) {
965 ALOGE("%s: Cannot set transform on unconnected stream", __FUNCTION__);
966 return INVALID_OPERATION;
967 }
968 res = native_window_set_buffers_transform(mConsumerInterface.get(),
969 transform);
970 if (res != OK) {
971 ALOGE("%s: Unable to configure stream transform to %x: %s (%d)",
972 __FUNCTION__, transform, strerror(-res), res);
973 }
974 return res;
975}
976
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700977status_t Camera2Device::StreamAdapter::dump(int fd,
978 const Vector<String16>& args) {
979 String8 result = String8::format(" Stream %d: %d x %d, format 0x%x\n",
980 mId, mWidth, mHeight, mFormat);
981 result.appendFormat(" size %d, usage 0x%x, requested format 0x%x\n",
982 mSize, mUsage, mFormatRequested);
983 result.appendFormat(" total buffers: %d, dequeued buffers: %d\n",
984 mTotalBuffers, mActiveBuffers);
985 result.appendFormat(" frame count: %d, last timestamp %lld\n",
986 mFrameCount, mLastTimestamp);
987 write(fd, result.string(), result.size());
988 return OK;
989}
990
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700991const camera2_stream_ops *Camera2Device::StreamAdapter::getStreamOps() {
992 return static_cast<camera2_stream_ops *>(this);
993}
994
995ANativeWindow* Camera2Device::StreamAdapter::toANW(
996 const camera2_stream_ops_t *w) {
997 return static_cast<const StreamAdapter*>(w)->mConsumerInterface.get();
998}
999
1000int Camera2Device::StreamAdapter::dequeue_buffer(const camera2_stream_ops_t *w,
1001 buffer_handle_t** buffer) {
1002 int res;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001003 StreamAdapter* stream =
1004 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
1005 if (stream->mState != ACTIVE) {
1006 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001007 return INVALID_OPERATION;
1008 }
1009
1010 ANativeWindow *a = toANW(w);
1011 ANativeWindowBuffer* anb;
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001012 res = native_window_dequeue_buffer_and_wait(a, &anb);
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001013 if (res != OK) {
1014 ALOGE("Stream %d dequeue: Error from native_window: %s (%d)", stream->mId,
1015 strerror(-res), res);
1016 return res;
1017 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001018
1019 *buffer = &(anb->handle);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001020 stream->mActiveBuffers++;
1021
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001022 ALOGVV("Stream %d dequeue: Buffer %p dequeued", stream->mId, (void*)(**buffer));
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001023 return res;
1024}
1025
1026int Camera2Device::StreamAdapter::enqueue_buffer(const camera2_stream_ops_t* w,
1027 int64_t timestamp,
1028 buffer_handle_t* buffer) {
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001029 StreamAdapter *stream =
1030 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001031 stream->mFrameCount++;
1032 ALOGVV("Stream %d enqueue: Frame %d (%p) captured at %lld ns",
James Dong6638f3b2012-09-05 16:46:36 -07001033 stream->mId, stream->mFrameCount, (void*)(*buffer), timestamp);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001034 int state = stream->mState;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001035 if (state != ACTIVE) {
1036 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1037 return INVALID_OPERATION;
1038 }
1039 ANativeWindow *a = toANW(w);
1040 status_t err;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001041
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001042 err = native_window_set_buffers_timestamp(a, timestamp);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001043 if (err != OK) {
1044 ALOGE("%s: Error setting timestamp on native window: %s (%d)",
1045 __FUNCTION__, strerror(-err), err);
1046 return err;
1047 }
1048 err = a->queueBuffer(a,
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001049 container_of(buffer, ANativeWindowBuffer, handle), -1);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001050 if (err != OK) {
1051 ALOGE("%s: Error queueing buffer to native window: %s (%d)",
1052 __FUNCTION__, strerror(-err), err);
James Dong31d377b2012-08-09 17:43:46 -07001053 return err;
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001054 }
James Dong31d377b2012-08-09 17:43:46 -07001055
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001056 stream->mActiveBuffers--;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001057 stream->mLastTimestamp = timestamp;
James Dong31d377b2012-08-09 17:43:46 -07001058 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001059}
1060
1061int Camera2Device::StreamAdapter::cancel_buffer(const camera2_stream_ops_t* w,
1062 buffer_handle_t* buffer) {
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001063 StreamAdapter *stream =
1064 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001065 ALOGVV("Stream %d cancel: Buffer %p",
1066 stream->mId, (void*)(*buffer));
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001067 if (stream->mState != ACTIVE) {
1068 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001069 return INVALID_OPERATION;
1070 }
James Dong31d377b2012-08-09 17:43:46 -07001071
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001072 ANativeWindow *a = toANW(w);
James Dong31d377b2012-08-09 17:43:46 -07001073 int err = a->cancelBuffer(a,
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001074 container_of(buffer, ANativeWindowBuffer, handle), -1);
James Dong31d377b2012-08-09 17:43:46 -07001075 if (err != OK) {
1076 ALOGE("%s: Error canceling buffer to native window: %s (%d)",
1077 __FUNCTION__, strerror(-err), err);
1078 return err;
1079 }
1080
1081 stream->mActiveBuffers--;
1082 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001083}
1084
1085int Camera2Device::StreamAdapter::set_crop(const camera2_stream_ops_t* w,
1086 int left, int top, int right, int bottom) {
1087 int state = static_cast<const StreamAdapter*>(w)->mState;
1088 if (state != ACTIVE) {
1089 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1090 return INVALID_OPERATION;
1091 }
1092 ANativeWindow *a = toANW(w);
1093 android_native_rect_t crop = { left, top, right, bottom };
1094 return native_window_set_crop(a, &crop);
1095}
1096
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001097
1098}; // namespace android