blob: 3390ff38ecbedfee22c26719b352ec460dee2c3c [file] [log] [blame]
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "Camera2Device"
18//#define LOG_NDEBUG 0
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -070019//#define LOG_NNDEBUG 0 // Per-frame verbose logging
20
21#ifdef LOG_NNDEBUG
22#define ALOGVV(...) ALOGV(__VA_ARGS__)
23#else
24#define ALOGVV(...) ((void)0)
25#endif
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070026
27#include <utils/Log.h>
28#include "Camera2Device.h"
29
30namespace android {
31
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070032Camera2Device::Camera2Device(int id):
33 mId(id),
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070034 mDevice(NULL)
35{
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -070036 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070037}
38
39Camera2Device::~Camera2Device()
40{
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -070041 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070042 if (mDevice) {
43 status_t res;
44 res = mDevice->common.close(&mDevice->common);
45 if (res != OK) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070046 ALOGE("%s: Could not close camera %d: %s (%d)",
47 __FUNCTION__,
48 mId, strerror(-res), res);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070049 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070050 mDevice = NULL;
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070051 }
52}
53
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070054status_t Camera2Device::initialize(camera_module_t *module)
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070055{
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -070056 ALOGV("%s: E", __FUNCTION__);
57
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070058 status_t res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070059 char name[10];
60 snprintf(name, sizeof(name), "%d", mId);
61
62 res = module->common.methods->open(&module->common, name,
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070063 reinterpret_cast<hw_device_t**>(&mDevice));
64
65 if (res != OK) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070066 ALOGE("%s: Could not open camera %d: %s (%d)", __FUNCTION__,
67 mId, strerror(-res), res);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070068 return res;
69 }
70
71 if (mDevice->common.version != CAMERA_DEVICE_API_VERSION_2_0) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070072 ALOGE("%s: Could not open camera %d: "
73 "Camera device is not version %x, reports %x instead",
74 __FUNCTION__, mId, CAMERA_DEVICE_API_VERSION_2_0,
75 mDevice->common.version);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070076 return BAD_VALUE;
77 }
78
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070079 camera_info info;
80 res = module->get_camera_info(mId, &info);
81 if (res != OK ) return res;
82
83 if (info.device_version != mDevice->common.version) {
84 ALOGE("%s: HAL reporting mismatched camera_info version (%x)"
85 " and device version (%x).", __FUNCTION__,
86 mDevice->common.version, info.device_version);
87 return BAD_VALUE;
88 }
89
90 mDeviceInfo = info.static_camera_characteristics;
91
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -070092 res = mRequestQueue.setConsumerDevice(mDevice);
93 if (res != OK) {
94 ALOGE("%s: Camera %d: Unable to connect request queue to device: %s (%d)",
95 __FUNCTION__, mId, strerror(-res), res);
96 return res;
97 }
98 res = mFrameQueue.setProducerDevice(mDevice);
99 if (res != OK) {
100 ALOGE("%s: Camera %d: Unable to connect frame queue to device: %s (%d)",
101 __FUNCTION__, mId, strerror(-res), res);
102 return res;
103 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700104
105 res = mDevice->ops->get_metadata_vendor_tag_ops(mDevice, &mVendorTagOps);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700106 if (res != OK ) {
107 ALOGE("%s: Camera %d: Unable to retrieve tag ops from device: %s (%d)",
108 __FUNCTION__, mId, strerror(-res), res);
109 return res;
110 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700111
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700112 setNotifyCallback(NULL);
113
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700114 return OK;
115}
116
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700117status_t Camera2Device::dump(int fd, const Vector<String16>& args) {
118
119 String8 result;
Eino-Ville Talvala97197152012-08-06 14:25:19 -0700120 int detailLevel = 0;
121 int n = args.size();
122 String16 detailOption("-d");
123 for (int i = 0; i + 1 < n; i++) {
124 if (args[i] == detailOption) {
125 String8 levelStr(args[i+1]);
126 detailLevel = atoi(levelStr.string());
127 }
128 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700129
Eino-Ville Talvala603b12e2012-08-08 09:25:58 -0700130 result.appendFormat(" Camera2Device[%d] dump (detail level %d):\n",
131 mId, detailLevel);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700132
Eino-Ville Talvala97197152012-08-06 14:25:19 -0700133 if (detailLevel > 0) {
134 result = " Request queue contents:\n";
135 write(fd, result.string(), result.size());
136 mRequestQueue.dump(fd, args);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700137
Eino-Ville Talvala97197152012-08-06 14:25:19 -0700138 result = " Frame queue contents:\n";
139 write(fd, result.string(), result.size());
140 mFrameQueue.dump(fd, args);
141 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700142
143 result = " Active streams:\n";
144 write(fd, result.string(), result.size());
145 for (StreamList::iterator s = mStreams.begin(); s != mStreams.end(); s++) {
146 (*s)->dump(fd, args);
147 }
148
149 result = " HAL device dump:\n";
150 write(fd, result.string(), result.size());
151
152 status_t res;
153 res = mDevice->ops->dump(mDevice, fd);
154
155 return res;
156}
157
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700158const CameraMetadata& Camera2Device::info() const {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700159 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700160
161 return mDeviceInfo;
162}
163
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700164status_t Camera2Device::capture(CameraMetadata &request) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700165 ALOGV("%s: E", __FUNCTION__);
166
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700167 mRequestQueue.enqueue(request.release());
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700168 return OK;
169}
170
171
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700172status_t Camera2Device::setStreamingRequest(const CameraMetadata &request) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700173 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700174 CameraMetadata streamRequest(request);
175 return mRequestQueue.setStreamSlot(streamRequest.release());
176}
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700177
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700178status_t Camera2Device::clearStreamingRequest() {
179 return mRequestQueue.setStreamSlot(NULL);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700180}
181
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700182status_t Camera2Device::createStream(sp<ANativeWindow> consumer,
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700183 uint32_t width, uint32_t height, int format, size_t size, int *id) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700184 status_t res;
185 ALOGV("%s: E", __FUNCTION__);
186
187 sp<StreamAdapter> stream = new StreamAdapter(mDevice);
188
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700189 res = stream->connectToDevice(consumer, width, height, format, size);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700190 if (res != OK) {
191 ALOGE("%s: Camera %d: Unable to create stream (%d x %d, format %x):"
192 "%s (%d)",
193 __FUNCTION__, mId, width, height, format, strerror(-res), res);
194 return res;
195 }
196
197 *id = stream->getId();
198
199 mStreams.push_back(stream);
200 return OK;
201}
202
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700203status_t Camera2Device::getStreamInfo(int id,
204 uint32_t *width, uint32_t *height, uint32_t *format) {
205 ALOGV("%s: E", __FUNCTION__);
206 bool found = false;
207 StreamList::iterator streamI;
208 for (streamI = mStreams.begin();
209 streamI != mStreams.end(); streamI++) {
210 if ((*streamI)->getId() == id) {
211 found = true;
212 break;
213 }
214 }
215 if (!found) {
216 ALOGE("%s: Camera %d: Stream %d does not exist",
217 __FUNCTION__, mId, id);
218 return BAD_VALUE;
219 }
220
221 if (width) *width = (*streamI)->getWidth();
222 if (height) *height = (*streamI)->getHeight();
223 if (format) *format = (*streamI)->getFormat();
224
225 return OK;
226}
227
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -0700228status_t Camera2Device::setStreamTransform(int id,
229 int transform) {
230 ALOGV("%s: E", __FUNCTION__);
231 bool found = false;
232 StreamList::iterator streamI;
233 for (streamI = mStreams.begin();
234 streamI != mStreams.end(); streamI++) {
235 if ((*streamI)->getId() == id) {
236 found = true;
237 break;
238 }
239 }
240 if (!found) {
241 ALOGE("%s: Camera %d: Stream %d does not exist",
242 __FUNCTION__, mId, id);
243 return BAD_VALUE;
244 }
245
246 return (*streamI)->setTransform(transform);
247}
248
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700249status_t Camera2Device::deleteStream(int id) {
250 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700251 bool found = false;
252 for (StreamList::iterator streamI = mStreams.begin();
253 streamI != mStreams.end(); streamI++) {
254 if ((*streamI)->getId() == id) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700255 status_t res = (*streamI)->release();
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700256 if (res != OK) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700257 ALOGE("%s: Unable to release stream %d from HAL device: "
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700258 "%s (%d)", __FUNCTION__, id, strerror(-res), res);
259 return res;
260 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700261 mStreams.erase(streamI);
262 found = true;
263 break;
264 }
265 }
266 if (!found) {
267 ALOGE("%s: Camera %d: Unable to find stream %d to delete",
268 __FUNCTION__, mId, id);
269 return BAD_VALUE;
270 }
271 return OK;
272}
273
274status_t Camera2Device::createDefaultRequest(int templateId,
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700275 CameraMetadata *request) {
276 status_t err;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700277 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700278 camera_metadata_t *rawRequest;
279 err = mDevice->ops->construct_default_request(
280 mDevice, templateId, &rawRequest);
281 request->acquire(rawRequest);
282 return err;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700283}
284
285status_t Camera2Device::waitUntilDrained() {
286 static const uint32_t kSleepTime = 50000; // 50 ms
287 static const uint32_t kMaxSleepTime = 10000000; // 10 s
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700288 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700289 if (mRequestQueue.getBufferCount() ==
290 CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS) return INVALID_OPERATION;
291
292 // TODO: Set up notifications from HAL, instead of sleeping here
293 uint32_t totalTime = 0;
294 while (mDevice->ops->get_in_progress_count(mDevice) > 0) {
295 usleep(kSleepTime);
296 totalTime += kSleepTime;
297 if (totalTime > kMaxSleepTime) {
298 ALOGE("%s: Waited %d us, requests still in flight", __FUNCTION__,
299 totalTime);
300 return TIMED_OUT;
301 }
302 }
303 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700304}
305
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700306status_t Camera2Device::setNotifyCallback(NotificationListener *listener) {
307 status_t res;
308 res = mDevice->ops->set_notify_callback(mDevice, notificationCallback,
309 reinterpret_cast<void*>(listener) );
310 if (res != OK) {
311 ALOGE("%s: Unable to set notification callback!", __FUNCTION__);
312 }
313 return res;
314}
315
316void Camera2Device::notificationCallback(int32_t msg_type,
317 int32_t ext1,
318 int32_t ext2,
319 int32_t ext3,
320 void *user) {
321 NotificationListener *listener = reinterpret_cast<NotificationListener*>(user);
322 ALOGV("%s: Notification %d, arguments %d, %d, %d", __FUNCTION__, msg_type,
323 ext1, ext2, ext3);
324 if (listener != NULL) {
325 switch (msg_type) {
326 case CAMERA2_MSG_ERROR:
327 listener->notifyError(ext1, ext2, ext3);
328 break;
329 case CAMERA2_MSG_SHUTTER: {
330 nsecs_t timestamp = (nsecs_t)ext2 | ((nsecs_t)(ext3) << 32 );
331 listener->notifyShutter(ext1, timestamp);
332 break;
333 }
334 case CAMERA2_MSG_AUTOFOCUS:
335 listener->notifyAutoFocus(ext1, ext2);
336 break;
337 case CAMERA2_MSG_AUTOEXPOSURE:
338 listener->notifyAutoExposure(ext1, ext2);
339 break;
340 case CAMERA2_MSG_AUTOWB:
341 listener->notifyAutoWhitebalance(ext1, ext2);
342 break;
343 default:
344 ALOGE("%s: Unknown notification %d (arguments %d, %d, %d)!",
345 __FUNCTION__, msg_type, ext1, ext2, ext3);
346 }
347 }
348}
349
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700350status_t Camera2Device::setFrameListener(FrameListener *listener) {
351 return mFrameQueue.setListener(listener);
352}
353
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700354status_t Camera2Device::getNextFrame(CameraMetadata *frame) {
355 status_t res;
356 camera_metadata_t *rawFrame;
357 res = mFrameQueue.dequeue(&rawFrame);
358 if (rawFrame == NULL) {
359 return NOT_ENOUGH_DATA;
360 } else if (res == OK) {
361 frame->acquire(rawFrame);
362 }
363 return res;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700364}
365
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700366status_t Camera2Device::triggerAutofocus(uint32_t id) {
367 status_t res;
368 ALOGV("%s: Triggering autofocus, id %d", __FUNCTION__, id);
369 res = mDevice->ops->trigger_action(mDevice,
370 CAMERA2_TRIGGER_AUTOFOCUS, id, 0);
371 if (res != OK) {
372 ALOGE("%s: Error triggering autofocus (id %d)",
373 __FUNCTION__, id);
374 }
375 return res;
376}
377
378status_t Camera2Device::triggerCancelAutofocus(uint32_t id) {
379 status_t res;
380 ALOGV("%s: Canceling autofocus, id %d", __FUNCTION__, id);
381 res = mDevice->ops->trigger_action(mDevice,
382 CAMERA2_TRIGGER_CANCEL_AUTOFOCUS, id, 0);
383 if (res != OK) {
384 ALOGE("%s: Error canceling autofocus (id %d)",
385 __FUNCTION__, id);
386 }
387 return res;
388}
389
390status_t Camera2Device::triggerPrecaptureMetering(uint32_t id) {
391 status_t res;
392 ALOGV("%s: Triggering precapture metering, id %d", __FUNCTION__, id);
393 res = mDevice->ops->trigger_action(mDevice,
394 CAMERA2_TRIGGER_PRECAPTURE_METERING, id, 0);
395 if (res != OK) {
396 ALOGE("%s: Error triggering precapture metering (id %d)",
397 __FUNCTION__, id);
398 }
399 return res;
400}
401
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700402/**
403 * Camera2Device::NotificationListener
404 */
405
406Camera2Device::NotificationListener::~NotificationListener() {
407}
408
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700409/**
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700410 * Camera2Device::FrameListener
411 */
412
413Camera2Device::FrameListener::~FrameListener() {
414}
415
416/**
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700417 * Camera2Device::MetadataQueue
418 */
419
420Camera2Device::MetadataQueue::MetadataQueue():
421 mDevice(NULL),
422 mFrameCount(0),
423 mCount(0),
424 mStreamSlotCount(0),
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700425 mSignalConsumer(true),
426 mListener(NULL)
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700427{
428 camera2_request_queue_src_ops::dequeue_request = consumer_dequeue;
429 camera2_request_queue_src_ops::request_count = consumer_buffer_count;
430 camera2_request_queue_src_ops::free_request = consumer_free;
431
432 camera2_frame_queue_dst_ops::dequeue_frame = producer_dequeue;
433 camera2_frame_queue_dst_ops::cancel_frame = producer_cancel;
434 camera2_frame_queue_dst_ops::enqueue_frame = producer_enqueue;
435}
436
437Camera2Device::MetadataQueue::~MetadataQueue() {
438 Mutex::Autolock l(mMutex);
439 freeBuffers(mEntries.begin(), mEntries.end());
440 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
441}
442
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700443// Connect to camera2 HAL as consumer (input requests/reprocessing)
444status_t Camera2Device::MetadataQueue::setConsumerDevice(camera2_device_t *d) {
445 status_t res;
446 res = d->ops->set_request_queue_src_ops(d,
447 this);
448 if (res != OK) return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700449 mDevice = d;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700450 return OK;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700451}
452
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700453status_t Camera2Device::MetadataQueue::setProducerDevice(camera2_device_t *d) {
454 status_t res;
455 res = d->ops->set_frame_queue_dst_ops(d,
456 this);
457 return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700458}
459
460// Real interfaces
461status_t Camera2Device::MetadataQueue::enqueue(camera_metadata_t *buf) {
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700462 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700463 Mutex::Autolock l(mMutex);
464
465 mCount++;
466 mEntries.push_back(buf);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700467
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700468 return signalConsumerLocked();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700469}
470
471int Camera2Device::MetadataQueue::getBufferCount() {
472 Mutex::Autolock l(mMutex);
473 if (mStreamSlotCount > 0) {
474 return CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS;
475 }
476 return mCount;
477}
478
479status_t Camera2Device::MetadataQueue::dequeue(camera_metadata_t **buf,
480 bool incrementCount)
481{
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700482 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700483 status_t res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700484 Mutex::Autolock l(mMutex);
485
486 if (mCount == 0) {
487 if (mStreamSlotCount == 0) {
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700488 ALOGVV("%s: Empty", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700489 *buf = NULL;
490 mSignalConsumer = true;
491 return OK;
492 }
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700493 ALOGVV("%s: Streaming %d frames to queue", __FUNCTION__,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700494 mStreamSlotCount);
495
496 for (List<camera_metadata_t*>::iterator slotEntry = mStreamSlot.begin();
497 slotEntry != mStreamSlot.end();
498 slotEntry++ ) {
499 size_t entries = get_camera_metadata_entry_count(*slotEntry);
500 size_t dataBytes = get_camera_metadata_data_count(*slotEntry);
501
502 camera_metadata_t *copy =
503 allocate_camera_metadata(entries, dataBytes);
504 append_camera_metadata(copy, *slotEntry);
505 mEntries.push_back(copy);
506 }
507 mCount = mStreamSlotCount;
508 }
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700509 ALOGVV("MetadataQueue: deque (%d buffers)", mCount);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700510 camera_metadata_t *b = *(mEntries.begin());
511 mEntries.erase(mEntries.begin());
512
513 if (incrementCount) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700514 camera_metadata_entry_t frameCount;
515 res = find_camera_metadata_entry(b,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700516 ANDROID_REQUEST_FRAME_COUNT,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700517 &frameCount);
518 if (res != OK) {
519 ALOGE("%s: Unable to add frame count: %s (%d)",
520 __FUNCTION__, strerror(-res), res);
521 } else {
522 *frameCount.data.i32 = mFrameCount;
523 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700524 mFrameCount++;
525 }
526
527 *buf = b;
528 mCount--;
529
530 return OK;
531}
532
533status_t Camera2Device::MetadataQueue::waitForBuffer(nsecs_t timeout)
534{
535 Mutex::Autolock l(mMutex);
536 status_t res;
537 while (mCount == 0) {
538 res = notEmpty.waitRelative(mMutex,timeout);
539 if (res != OK) return res;
540 }
541 return OK;
542}
543
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700544status_t Camera2Device::MetadataQueue::setListener(FrameListener *listener) {
545 Mutex::Autolock l(mMutex);
546 mListener = listener;
547 return OK;
548}
549
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700550status_t Camera2Device::MetadataQueue::setStreamSlot(camera_metadata_t *buf)
551{
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700552 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700553 Mutex::Autolock l(mMutex);
554 if (buf == NULL) {
555 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
556 mStreamSlotCount = 0;
557 return OK;
558 }
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700559 camera_metadata_t *buf2 = clone_camera_metadata(buf);
560 if (!buf2) {
561 ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__);
562 return NO_MEMORY;
563 }
564
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700565 if (mStreamSlotCount > 1) {
566 List<camera_metadata_t*>::iterator deleter = ++mStreamSlot.begin();
567 freeBuffers(++mStreamSlot.begin(), mStreamSlot.end());
568 mStreamSlotCount = 1;
569 }
570 if (mStreamSlotCount == 1) {
571 free_camera_metadata( *(mStreamSlot.begin()) );
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700572 *(mStreamSlot.begin()) = buf2;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700573 } else {
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700574 mStreamSlot.push_front(buf2);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700575 mStreamSlotCount = 1;
576 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700577 return signalConsumerLocked();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700578}
579
580status_t Camera2Device::MetadataQueue::setStreamSlot(
581 const List<camera_metadata_t*> &bufs)
582{
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700583 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700584 Mutex::Autolock l(mMutex);
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700585 status_t res;
586
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700587 if (mStreamSlotCount > 0) {
588 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
589 }
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700590 mStreamSlotCount = 0;
591 for (List<camera_metadata_t*>::const_iterator r = bufs.begin();
592 r != bufs.end(); r++) {
593 camera_metadata_t *r2 = clone_camera_metadata(*r);
594 if (!r2) {
595 ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__);
596 return NO_MEMORY;
597 }
598 mStreamSlot.push_back(r2);
599 mStreamSlotCount++;
600 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700601 return signalConsumerLocked();
602}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700603
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700604status_t Camera2Device::MetadataQueue::dump(int fd,
605 const Vector<String16>& args) {
606 String8 result;
607 status_t notLocked;
608 notLocked = mMutex.tryLock();
609 if (notLocked) {
610 result.append(" (Unable to lock queue mutex)\n");
611 }
612 result.appendFormat(" Current frame number: %d\n", mFrameCount);
613 if (mStreamSlotCount == 0) {
614 result.append(" Stream slot: Empty\n");
615 write(fd, result.string(), result.size());
616 } else {
617 result.appendFormat(" Stream slot: %d entries\n",
618 mStreamSlot.size());
619 int i = 0;
620 for (List<camera_metadata_t*>::iterator r = mStreamSlot.begin();
621 r != mStreamSlot.end(); r++) {
622 result = String8::format(" Stream slot buffer %d:\n", i);
623 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700624 dump_indented_camera_metadata(*r, fd, 2, 10);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700625 i++;
626 }
627 }
628 if (mEntries.size() == 0) {
629 result = " Main queue is empty\n";
630 write(fd, result.string(), result.size());
631 } else {
632 result = String8::format(" Main queue has %d entries:\n",
633 mEntries.size());
634 int i = 0;
635 for (List<camera_metadata_t*>::iterator r = mEntries.begin();
636 r != mEntries.end(); r++) {
637 result = String8::format(" Queue entry %d:\n", i);
638 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700639 dump_indented_camera_metadata(*r, fd, 2, 10);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700640 i++;
641 }
642 }
643
644 if (notLocked == 0) {
645 mMutex.unlock();
646 }
647
648 return OK;
649}
650
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700651status_t Camera2Device::MetadataQueue::signalConsumerLocked() {
652 status_t res = OK;
653 notEmpty.signal();
654 if (mSignalConsumer && mDevice != NULL) {
655 mSignalConsumer = false;
656
657 mMutex.unlock();
658 ALOGV("%s: Signaling consumer", __FUNCTION__);
659 res = mDevice->ops->notify_request_queue_not_empty(mDevice);
660 mMutex.lock();
661 }
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700662 if (mListener != NULL) {
663 FrameListener *listener = mListener;
664 mMutex.unlock();
665 ALOGVV("%s: Signaling listener", __FUNCTION__);
666 listener->onNewFrameAvailable();
667 mMutex.lock();
668 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700669 return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700670}
671
672status_t Camera2Device::MetadataQueue::freeBuffers(
673 List<camera_metadata_t*>::iterator start,
674 List<camera_metadata_t*>::iterator end)
675{
676 while (start != end) {
677 free_camera_metadata(*start);
678 start = mStreamSlot.erase(start);
679 }
680 return OK;
681}
682
683Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
684 const camera2_request_queue_src_ops_t *q)
685{
686 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
687 return const_cast<MetadataQueue*>(cmq);
688}
689
690Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
691 const camera2_frame_queue_dst_ops_t *q)
692{
693 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
694 return const_cast<MetadataQueue*>(cmq);
695}
696
697int Camera2Device::MetadataQueue::consumer_buffer_count(
698 const camera2_request_queue_src_ops_t *q)
699{
700 MetadataQueue *queue = getInstance(q);
701 return queue->getBufferCount();
702}
703
704int Camera2Device::MetadataQueue::consumer_dequeue(
705 const camera2_request_queue_src_ops_t *q,
706 camera_metadata_t **buffer)
707{
708 MetadataQueue *queue = getInstance(q);
709 return queue->dequeue(buffer, true);
710}
711
712int Camera2Device::MetadataQueue::consumer_free(
713 const camera2_request_queue_src_ops_t *q,
714 camera_metadata_t *old_buffer)
715{
716 MetadataQueue *queue = getInstance(q);
717 free_camera_metadata(old_buffer);
718 return OK;
719}
720
721int Camera2Device::MetadataQueue::producer_dequeue(
722 const camera2_frame_queue_dst_ops_t *q,
723 size_t entries, size_t bytes,
724 camera_metadata_t **buffer)
725{
726 camera_metadata_t *new_buffer =
727 allocate_camera_metadata(entries, bytes);
728 if (new_buffer == NULL) return NO_MEMORY;
729 *buffer = new_buffer;
730 return OK;
731}
732
733int Camera2Device::MetadataQueue::producer_cancel(
734 const camera2_frame_queue_dst_ops_t *q,
735 camera_metadata_t *old_buffer)
736{
737 free_camera_metadata(old_buffer);
738 return OK;
739}
740
741int Camera2Device::MetadataQueue::producer_enqueue(
742 const camera2_frame_queue_dst_ops_t *q,
743 camera_metadata_t *filled_buffer)
744{
745 MetadataQueue *queue = getInstance(q);
746 return queue->enqueue(filled_buffer);
747}
748
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700749/**
750 * Camera2Device::StreamAdapter
751 */
752
753#ifndef container_of
754#define container_of(ptr, type, member) \
755 (type *)((char*)(ptr) - offsetof(type, member))
756#endif
757
758Camera2Device::StreamAdapter::StreamAdapter(camera2_device_t *d):
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700759 mState(RELEASED),
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700760 mDevice(d),
761 mId(-1),
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700762 mWidth(0), mHeight(0), mFormat(0), mSize(0), mUsage(0),
763 mMaxProducerBuffers(0), mMaxConsumerBuffers(0),
764 mTotalBuffers(0),
765 mFormatRequested(0),
766 mActiveBuffers(0),
767 mFrameCount(0),
768 mLastTimestamp(0)
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700769{
770 camera2_stream_ops::dequeue_buffer = dequeue_buffer;
771 camera2_stream_ops::enqueue_buffer = enqueue_buffer;
772 camera2_stream_ops::cancel_buffer = cancel_buffer;
773 camera2_stream_ops::set_crop = set_crop;
774}
775
776Camera2Device::StreamAdapter::~StreamAdapter() {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700777 if (mState != RELEASED) {
778 release();
779 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700780}
781
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700782status_t Camera2Device::StreamAdapter::connectToDevice(
783 sp<ANativeWindow> consumer,
784 uint32_t width, uint32_t height, int format, size_t size) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700785 status_t res;
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700786 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700787
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700788 if (mState != RELEASED) return INVALID_OPERATION;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700789 if (consumer == NULL) {
790 ALOGE("%s: Null consumer passed to stream adapter", __FUNCTION__);
791 return BAD_VALUE;
792 }
793
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700794 ALOGV("%s: New stream parameters %d x %d, format 0x%x, size %d",
795 __FUNCTION__, width, height, format, size);
796
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700797 mConsumerInterface = consumer;
798 mWidth = width;
799 mHeight = height;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700800 mSize = (format == HAL_PIXEL_FORMAT_BLOB) ? size : 0;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700801 mFormatRequested = format;
802
803 // Allocate device-side stream interface
804
805 uint32_t id;
806 uint32_t formatActual;
807 uint32_t usage;
808 uint32_t maxBuffers = 2;
809 res = mDevice->ops->allocate_stream(mDevice,
810 mWidth, mHeight, mFormatRequested, getStreamOps(),
811 &id, &formatActual, &usage, &maxBuffers);
812 if (res != OK) {
813 ALOGE("%s: Device stream allocation failed: %s (%d)",
814 __FUNCTION__, strerror(-res), res);
815 return res;
816 }
817
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700818 ALOGV("%s: Allocated stream id %d, actual format 0x%x, "
819 "usage 0x%x, producer wants %d buffers", __FUNCTION__,
820 id, formatActual, usage, maxBuffers);
821
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700822 mId = id;
823 mFormat = formatActual;
824 mUsage = usage;
825 mMaxProducerBuffers = maxBuffers;
826
827 mState = ALLOCATED;
828
829 // Configure consumer-side ANativeWindow interface
830 res = native_window_api_connect(mConsumerInterface.get(),
831 NATIVE_WINDOW_API_CAMERA);
832 if (res != OK) {
833 ALOGE("%s: Unable to connect to native window for stream %d",
834 __FUNCTION__, mId);
835
836 return res;
837 }
838
839 mState = CONNECTED;
840
841 res = native_window_set_usage(mConsumerInterface.get(), mUsage);
842 if (res != OK) {
843 ALOGE("%s: Unable to configure usage %08x for stream %d",
844 __FUNCTION__, mUsage, mId);
845 return res;
846 }
847
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -0700848 res = native_window_set_scaling_mode(mConsumerInterface.get(),
849 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
850 if (res != OK) {
851 ALOGE("%s: Unable to configure stream scaling: %s (%d)",
852 __FUNCTION__, strerror(-res), res);
853 return res;
854 }
855
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -0700856 res = setTransform(0);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -0700857 if (res != OK) {
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -0700858 return res;
859 }
860
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700861 if (mFormat == HAL_PIXEL_FORMAT_BLOB) {
862 res = native_window_set_buffers_geometry(mConsumerInterface.get(),
863 mSize, 1, mFormat);
864 if (res != OK) {
865 ALOGE("%s: Unable to configure compressed stream buffer geometry"
866 " %d x %d, size %d for stream %d",
867 __FUNCTION__, mWidth, mHeight, mSize, mId);
868 return res;
869 }
870 } else {
871 res = native_window_set_buffers_geometry(mConsumerInterface.get(),
872 mWidth, mHeight, mFormat);
873 if (res != OK) {
874 ALOGE("%s: Unable to configure stream buffer geometry"
875 " %d x %d, format 0x%x for stream %d",
876 __FUNCTION__, mWidth, mHeight, mFormat, mId);
877 return res;
878 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700879 }
880
881 int maxConsumerBuffers;
882 res = mConsumerInterface->query(mConsumerInterface.get(),
883 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &maxConsumerBuffers);
884 if (res != OK) {
885 ALOGE("%s: Unable to query consumer undequeued"
886 " buffer count for stream %d", __FUNCTION__, mId);
887 return res;
888 }
889 mMaxConsumerBuffers = maxConsumerBuffers;
890
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700891 ALOGV("%s: Consumer wants %d buffers", __FUNCTION__,
892 mMaxConsumerBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700893
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700894 mTotalBuffers = mMaxConsumerBuffers + mMaxProducerBuffers;
895 mActiveBuffers = 0;
896 mFrameCount = 0;
897 mLastTimestamp = 0;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700898
899 res = native_window_set_buffer_count(mConsumerInterface.get(),
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700900 mTotalBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700901 if (res != OK) {
902 ALOGE("%s: Unable to set buffer count for stream %d",
903 __FUNCTION__, mId);
904 return res;
905 }
906
907 // Register allocated buffers with HAL device
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700908 buffer_handle_t *buffers = new buffer_handle_t[mTotalBuffers];
909 ANativeWindowBuffer **anwBuffers = new ANativeWindowBuffer*[mTotalBuffers];
910 uint32_t bufferIdx = 0;
911 for (; bufferIdx < mTotalBuffers; bufferIdx++) {
Jamie Gennis1e5b2b32012-06-13 16:29:51 -0700912 res = native_window_dequeue_buffer_and_wait(mConsumerInterface.get(),
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700913 &anwBuffers[bufferIdx]);
914 if (res != OK) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700915 ALOGE("%s: Unable to dequeue buffer %d for initial registration for "
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700916 "stream %d", __FUNCTION__, bufferIdx, mId);
917 goto cleanUpBuffers;
918 }
919
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700920 buffers[bufferIdx] = anwBuffers[bufferIdx]->handle;
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -0700921 ALOGV("%s: Buffer %p allocated", __FUNCTION__, (void*)(buffers[bufferIdx]));
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700922 }
923
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -0700924 ALOGV("%s: Registering %d buffers with camera HAL", __FUNCTION__, mTotalBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700925 res = mDevice->ops->register_stream_buffers(mDevice,
926 mId,
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700927 mTotalBuffers,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700928 buffers);
929 if (res != OK) {
930 ALOGE("%s: Unable to register buffers with HAL device for stream %d",
931 __FUNCTION__, mId);
932 } else {
933 mState = ACTIVE;
934 }
935
936cleanUpBuffers:
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -0700937 ALOGV("%s: Cleaning up %d buffers", __FUNCTION__, bufferIdx);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700938 for (uint32_t i = 0; i < bufferIdx; i++) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700939 res = mConsumerInterface->cancelBuffer(mConsumerInterface.get(),
Jamie Gennis1e5b2b32012-06-13 16:29:51 -0700940 anwBuffers[i], -1);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700941 if (res != OK) {
942 ALOGE("%s: Unable to cancel buffer %d after registration",
943 __FUNCTION__, i);
944 }
945 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700946 delete[] anwBuffers;
947 delete[] buffers;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700948
949 return res;
950}
951
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700952status_t Camera2Device::StreamAdapter::release() {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700953 status_t res;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700954 ALOGV("%s: Releasing stream %d", __FUNCTION__, mId);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700955 if (mState >= ALLOCATED) {
956 res = mDevice->ops->release_stream(mDevice, mId);
957 if (res != OK) {
958 ALOGE("%s: Unable to release stream %d",
959 __FUNCTION__, mId);
960 return res;
961 }
962 }
963 if (mState >= CONNECTED) {
964 res = native_window_api_disconnect(mConsumerInterface.get(),
965 NATIVE_WINDOW_API_CAMERA);
966 if (res != OK) {
967 ALOGE("%s: Unable to disconnect stream %d from native window",
968 __FUNCTION__, mId);
969 return res;
970 }
971 }
972 mId = -1;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700973 mState = RELEASED;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700974 return OK;
975}
976
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -0700977status_t Camera2Device::StreamAdapter::setTransform(int transform) {
978 status_t res;
979 if (mState < CONNECTED) {
980 ALOGE("%s: Cannot set transform on unconnected stream", __FUNCTION__);
981 return INVALID_OPERATION;
982 }
983 res = native_window_set_buffers_transform(mConsumerInterface.get(),
984 transform);
985 if (res != OK) {
986 ALOGE("%s: Unable to configure stream transform to %x: %s (%d)",
987 __FUNCTION__, transform, strerror(-res), res);
988 }
989 return res;
990}
991
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700992status_t Camera2Device::StreamAdapter::dump(int fd,
993 const Vector<String16>& args) {
994 String8 result = String8::format(" Stream %d: %d x %d, format 0x%x\n",
995 mId, mWidth, mHeight, mFormat);
996 result.appendFormat(" size %d, usage 0x%x, requested format 0x%x\n",
997 mSize, mUsage, mFormatRequested);
998 result.appendFormat(" total buffers: %d, dequeued buffers: %d\n",
999 mTotalBuffers, mActiveBuffers);
1000 result.appendFormat(" frame count: %d, last timestamp %lld\n",
1001 mFrameCount, mLastTimestamp);
1002 write(fd, result.string(), result.size());
1003 return OK;
1004}
1005
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001006const camera2_stream_ops *Camera2Device::StreamAdapter::getStreamOps() {
1007 return static_cast<camera2_stream_ops *>(this);
1008}
1009
1010ANativeWindow* Camera2Device::StreamAdapter::toANW(
1011 const camera2_stream_ops_t *w) {
1012 return static_cast<const StreamAdapter*>(w)->mConsumerInterface.get();
1013}
1014
1015int Camera2Device::StreamAdapter::dequeue_buffer(const camera2_stream_ops_t *w,
1016 buffer_handle_t** buffer) {
1017 int res;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001018 StreamAdapter* stream =
1019 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
1020 if (stream->mState != ACTIVE) {
1021 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001022 return INVALID_OPERATION;
1023 }
1024
1025 ANativeWindow *a = toANW(w);
1026 ANativeWindowBuffer* anb;
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001027 res = native_window_dequeue_buffer_and_wait(a, &anb);
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001028 if (res != OK) {
1029 ALOGE("Stream %d dequeue: Error from native_window: %s (%d)", stream->mId,
1030 strerror(-res), res);
1031 return res;
1032 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001033
1034 *buffer = &(anb->handle);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001035 stream->mActiveBuffers++;
1036
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001037 ALOGVV("Stream %d dequeue: Buffer %p dequeued", stream->mId, (void*)(**buffer));
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001038 return res;
1039}
1040
1041int Camera2Device::StreamAdapter::enqueue_buffer(const camera2_stream_ops_t* w,
1042 int64_t timestamp,
1043 buffer_handle_t* buffer) {
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001044 StreamAdapter *stream =
1045 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001046 stream->mFrameCount++;
1047 ALOGVV("Stream %d enqueue: Frame %d (%p) captured at %lld ns",
1048 stream->mId, mFrameCount, (void*)(*buffer), timestamp);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001049 int state = stream->mState;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001050 if (state != ACTIVE) {
1051 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1052 return INVALID_OPERATION;
1053 }
1054 ANativeWindow *a = toANW(w);
1055 status_t err;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001056
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001057 err = native_window_set_buffers_timestamp(a, timestamp);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001058 if (err != OK) {
1059 ALOGE("%s: Error setting timestamp on native window: %s (%d)",
1060 __FUNCTION__, strerror(-err), err);
1061 return err;
1062 }
1063 err = a->queueBuffer(a,
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001064 container_of(buffer, ANativeWindowBuffer, handle), -1);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001065 if (err != OK) {
1066 ALOGE("%s: Error queueing buffer to native window: %s (%d)",
1067 __FUNCTION__, strerror(-err), err);
James Dong31d377b2012-08-09 17:43:46 -07001068 return err;
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001069 }
James Dong31d377b2012-08-09 17:43:46 -07001070
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001071 stream->mActiveBuffers--;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001072 stream->mLastTimestamp = timestamp;
James Dong31d377b2012-08-09 17:43:46 -07001073 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001074}
1075
1076int Camera2Device::StreamAdapter::cancel_buffer(const camera2_stream_ops_t* w,
1077 buffer_handle_t* buffer) {
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001078 StreamAdapter *stream =
1079 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001080 ALOGVV("Stream %d cancel: Buffer %p",
1081 stream->mId, (void*)(*buffer));
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001082 if (stream->mState != ACTIVE) {
1083 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001084 return INVALID_OPERATION;
1085 }
James Dong31d377b2012-08-09 17:43:46 -07001086
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001087 ANativeWindow *a = toANW(w);
James Dong31d377b2012-08-09 17:43:46 -07001088 int err = a->cancelBuffer(a,
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001089 container_of(buffer, ANativeWindowBuffer, handle), -1);
James Dong31d377b2012-08-09 17:43:46 -07001090 if (err != OK) {
1091 ALOGE("%s: Error canceling buffer to native window: %s (%d)",
1092 __FUNCTION__, strerror(-err), err);
1093 return err;
1094 }
1095
1096 stream->mActiveBuffers--;
1097 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001098}
1099
1100int Camera2Device::StreamAdapter::set_crop(const camera2_stream_ops_t* w,
1101 int left, int top, int right, int bottom) {
1102 int state = static_cast<const StreamAdapter*>(w)->mState;
1103 if (state != ACTIVE) {
1104 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1105 return INVALID_OPERATION;
1106 }
1107 ANativeWindow *a = toANW(w);
1108 android_native_rect_t crop = { left, top, right, bottom };
1109 return native_window_set_crop(a, &crop);
1110}
1111
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001112
1113}; // namespace android