blob: 2e4098e50f97bd13e61f1ca1ac56e42bdb4e0db8 [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
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -070017#define LOG_TAG "Camera2-Device"
18#define ATRACE_TAG ATRACE_TAG_CAMERA
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070019//#define LOG_NDEBUG 0
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -070020//#define LOG_NNDEBUG 0 // Per-frame verbose logging
21
22#ifdef LOG_NNDEBUG
23#define ALOGVV(...) ALOGV(__VA_ARGS__)
24#else
25#define ALOGVV(...) ((void)0)
26#endif
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070027
28#include <utils/Log.h>
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -070029#include <utils/Trace.h>
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070030#include "Camera2Device.h"
31
32namespace android {
33
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070034Camera2Device::Camera2Device(int id):
35 mId(id),
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070036 mDevice(NULL)
37{
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -070038 ATRACE_CALL();
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -070039 ALOGV("%s: Created device for camera %d", __FUNCTION__, id);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070040}
41
42Camera2Device::~Camera2Device()
43{
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -070044 ATRACE_CALL();
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -070045 disconnect();
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070046}
47
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070048status_t Camera2Device::initialize(camera_module_t *module)
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070049{
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -070050 ATRACE_CALL();
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -070051 ALOGV("%s: Initializing device for camera %d", __FUNCTION__, mId);
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -070052 if (mDevice != NULL) {
53 ALOGE("%s: Already initialized!", __FUNCTION__);
54 return INVALID_OPERATION;
55 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -070056
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070057 status_t res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070058 char name[10];
59 snprintf(name, sizeof(name), "%d", mId);
60
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -070061 camera2_device_t *device;
62
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070063 res = module->common.methods->open(&module->common, name,
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -070064 reinterpret_cast<hw_device_t**>(&device));
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070065
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
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -070072 if (device->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,
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -070076 device->common.version);
77 device->common.close(&device->common);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070078 return BAD_VALUE;
79 }
80
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070081 camera_info info;
82 res = module->get_camera_info(mId, &info);
83 if (res != OK ) return res;
84
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -070085 if (info.device_version != device->common.version) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070086 ALOGE("%s: HAL reporting mismatched camera_info version (%x)"
87 " and device version (%x).", __FUNCTION__,
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -070088 device->common.version, info.device_version);
89 device->common.close(&device->common);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070090 return BAD_VALUE;
91 }
92
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -070093 res = mRequestQueue.setConsumerDevice(device);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -070094 if (res != OK) {
95 ALOGE("%s: Camera %d: Unable to connect request queue to device: %s (%d)",
96 __FUNCTION__, mId, strerror(-res), res);
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -070097 device->common.close(&device->common);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -070098 return res;
99 }
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -0700100 res = mFrameQueue.setProducerDevice(device);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700101 if (res != OK) {
102 ALOGE("%s: Camera %d: Unable to connect frame queue to device: %s (%d)",
103 __FUNCTION__, mId, strerror(-res), res);
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -0700104 device->common.close(&device->common);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700105 return res;
106 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700107
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -0700108 res = device->ops->get_metadata_vendor_tag_ops(device, &mVendorTagOps);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700109 if (res != OK ) {
110 ALOGE("%s: Camera %d: Unable to retrieve tag ops from device: %s (%d)",
111 __FUNCTION__, mId, strerror(-res), res);
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -0700112 device->common.close(&device->common);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700113 return res;
114 }
Shuzhen Wang092fe442012-08-31 10:24:22 -0700115 res = set_camera_metadata_vendor_tag_ops(mVendorTagOps);
116 if (res != OK) {
117 ALOGE("%s: Camera %d: Unable to set tag ops: %s (%d)",
118 __FUNCTION__, mId, strerror(-res), res);
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -0700119 device->common.close(&device->common);
Shuzhen Wang092fe442012-08-31 10:24:22 -0700120 return res;
121 }
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -0700122 res = device->ops->set_notify_callback(device, notificationCallback,
123 NULL);
124 if (res != OK) {
125 ALOGE("%s: Camera %d: Unable to initialize notification callback!",
126 __FUNCTION__, mId);
127 device->common.close(&device->common);
128 return res;
129 }
130
131 mDeviceInfo = info.static_camera_characteristics;
132 mDevice = device;
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700133
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700134 return OK;
135}
136
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -0700137status_t Camera2Device::disconnect() {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700138 ATRACE_CALL();
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -0700139 status_t res = OK;
140 if (mDevice) {
141 ALOGV("%s: Closing device for camera %d", __FUNCTION__, mId);
142
143 int inProgressCount = mDevice->ops->get_in_progress_count(mDevice);
144 if (inProgressCount > 0) {
145 ALOGW("%s: Closing camera device %d with %d requests in flight!",
146 __FUNCTION__, mId, inProgressCount);
147 }
Eino-Ville Talvalac7d9afd2012-09-24 13:44:07 -0700148 mReprocessStreams.clear();
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -0700149 mStreams.clear();
150 res = mDevice->common.close(&mDevice->common);
151 if (res != OK) {
152 ALOGE("%s: Could not close camera %d: %s (%d)",
153 __FUNCTION__,
154 mId, strerror(-res), res);
155 }
156 mDevice = NULL;
157 ALOGV("%s: Shutdown complete", __FUNCTION__);
158 }
159 return res;
160}
161
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700162status_t Camera2Device::dump(int fd, const Vector<String16>& args) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700163 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700164 String8 result;
Eino-Ville Talvala97197152012-08-06 14:25:19 -0700165 int detailLevel = 0;
166 int n = args.size();
167 String16 detailOption("-d");
168 for (int i = 0; i + 1 < n; i++) {
169 if (args[i] == detailOption) {
170 String8 levelStr(args[i+1]);
171 detailLevel = atoi(levelStr.string());
172 }
173 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700174
Eino-Ville Talvala603b12e2012-08-08 09:25:58 -0700175 result.appendFormat(" Camera2Device[%d] dump (detail level %d):\n",
176 mId, detailLevel);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700177
Eino-Ville Talvala97197152012-08-06 14:25:19 -0700178 if (detailLevel > 0) {
179 result = " Request queue contents:\n";
180 write(fd, result.string(), result.size());
181 mRequestQueue.dump(fd, args);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700182
Eino-Ville Talvala97197152012-08-06 14:25:19 -0700183 result = " Frame queue contents:\n";
184 write(fd, result.string(), result.size());
185 mFrameQueue.dump(fd, args);
186 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700187
188 result = " Active streams:\n";
189 write(fd, result.string(), result.size());
190 for (StreamList::iterator s = mStreams.begin(); s != mStreams.end(); s++) {
191 (*s)->dump(fd, args);
192 }
193
194 result = " HAL device dump:\n";
195 write(fd, result.string(), result.size());
196
197 status_t res;
198 res = mDevice->ops->dump(mDevice, fd);
199
200 return res;
201}
202
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700203const camera2::CameraMetadata& Camera2Device::info() const {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700204 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700205
206 return mDeviceInfo;
207}
208
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700209status_t Camera2Device::capture(CameraMetadata &request) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700210 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700211 ALOGV("%s: E", __FUNCTION__);
212
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700213 mRequestQueue.enqueue(request.release());
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700214 return OK;
215}
216
217
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700218status_t Camera2Device::setStreamingRequest(const CameraMetadata &request) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700219 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700220 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700221 CameraMetadata streamRequest(request);
222 return mRequestQueue.setStreamSlot(streamRequest.release());
223}
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700224
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700225status_t Camera2Device::clearStreamingRequest() {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700226 ATRACE_CALL();
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700227 return mRequestQueue.setStreamSlot(NULL);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700228}
229
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700230status_t Camera2Device::createStream(sp<ANativeWindow> consumer,
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700231 uint32_t width, uint32_t height, int format, size_t size, int *id) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700232 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700233 status_t res;
234 ALOGV("%s: E", __FUNCTION__);
235
236 sp<StreamAdapter> stream = new StreamAdapter(mDevice);
237
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700238 res = stream->connectToDevice(consumer, width, height, format, size);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700239 if (res != OK) {
240 ALOGE("%s: Camera %d: Unable to create stream (%d x %d, format %x):"
241 "%s (%d)",
242 __FUNCTION__, mId, width, height, format, strerror(-res), res);
243 return res;
244 }
245
246 *id = stream->getId();
247
248 mStreams.push_back(stream);
249 return OK;
250}
251
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700252status_t Camera2Device::createReprocessStreamFromStream(int outputId, int *id) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700253 ATRACE_CALL();
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700254 status_t res;
255 ALOGV("%s: E", __FUNCTION__);
256
257 bool found = false;
258 StreamList::iterator streamI;
259 for (streamI = mStreams.begin();
260 streamI != mStreams.end(); streamI++) {
261 if ((*streamI)->getId() == outputId) {
262 found = true;
263 break;
264 }
265 }
266 if (!found) {
267 ALOGE("%s: Camera %d: Output stream %d doesn't exist; can't create "
268 "reprocess stream from it!", __FUNCTION__, mId, outputId);
269 return BAD_VALUE;
270 }
271
272 sp<ReprocessStreamAdapter> stream = new ReprocessStreamAdapter(mDevice);
273
274 res = stream->connectToDevice((*streamI));
275 if (res != OK) {
276 ALOGE("%s: Camera %d: Unable to create reprocessing stream from "\
277 "stream %d: %s (%d)", __FUNCTION__, mId, outputId,
278 strerror(-res), res);
279 return res;
280 }
281
282 *id = stream->getId();
283
284 mReprocessStreams.push_back(stream);
285 return OK;
286}
287
288
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700289status_t Camera2Device::getStreamInfo(int id,
290 uint32_t *width, uint32_t *height, uint32_t *format) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700291 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700292 ALOGV("%s: E", __FUNCTION__);
293 bool found = false;
294 StreamList::iterator streamI;
295 for (streamI = mStreams.begin();
296 streamI != mStreams.end(); streamI++) {
297 if ((*streamI)->getId() == id) {
298 found = true;
299 break;
300 }
301 }
302 if (!found) {
303 ALOGE("%s: Camera %d: Stream %d does not exist",
304 __FUNCTION__, mId, id);
305 return BAD_VALUE;
306 }
307
308 if (width) *width = (*streamI)->getWidth();
309 if (height) *height = (*streamI)->getHeight();
310 if (format) *format = (*streamI)->getFormat();
311
312 return OK;
313}
314
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -0700315status_t Camera2Device::setStreamTransform(int id,
316 int transform) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700317 ATRACE_CALL();
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -0700318 ALOGV("%s: E", __FUNCTION__);
319 bool found = false;
320 StreamList::iterator streamI;
321 for (streamI = mStreams.begin();
322 streamI != mStreams.end(); streamI++) {
323 if ((*streamI)->getId() == id) {
324 found = true;
325 break;
326 }
327 }
328 if (!found) {
329 ALOGE("%s: Camera %d: Stream %d does not exist",
330 __FUNCTION__, mId, id);
331 return BAD_VALUE;
332 }
333
334 return (*streamI)->setTransform(transform);
335}
336
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700337status_t Camera2Device::deleteStream(int id) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700338 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700339 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700340 bool found = false;
341 for (StreamList::iterator streamI = mStreams.begin();
342 streamI != mStreams.end(); streamI++) {
343 if ((*streamI)->getId() == id) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700344 status_t res = (*streamI)->release();
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700345 if (res != OK) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700346 ALOGE("%s: Unable to release stream %d from HAL device: "
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700347 "%s (%d)", __FUNCTION__, id, strerror(-res), res);
348 return res;
349 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700350 mStreams.erase(streamI);
351 found = true;
352 break;
353 }
354 }
355 if (!found) {
356 ALOGE("%s: Camera %d: Unable to find stream %d to delete",
357 __FUNCTION__, mId, id);
358 return BAD_VALUE;
359 }
360 return OK;
361}
362
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700363status_t Camera2Device::deleteReprocessStream(int id) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700364 ATRACE_CALL();
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700365 ALOGV("%s: E", __FUNCTION__);
366 bool found = false;
367 for (ReprocessStreamList::iterator streamI = mReprocessStreams.begin();
368 streamI != mReprocessStreams.end(); streamI++) {
369 if ((*streamI)->getId() == id) {
370 status_t res = (*streamI)->release();
371 if (res != OK) {
372 ALOGE("%s: Unable to release reprocess stream %d from "
373 "HAL device: %s (%d)", __FUNCTION__, id,
374 strerror(-res), res);
375 return res;
376 }
377 mReprocessStreams.erase(streamI);
378 found = true;
379 break;
380 }
381 }
382 if (!found) {
383 ALOGE("%s: Camera %d: Unable to find stream %d to delete",
384 __FUNCTION__, mId, id);
385 return BAD_VALUE;
386 }
387 return OK;
388}
389
390
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700391status_t Camera2Device::createDefaultRequest(int templateId,
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700392 CameraMetadata *request) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700393 ATRACE_CALL();
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700394 status_t err;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700395 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700396 camera_metadata_t *rawRequest;
397 err = mDevice->ops->construct_default_request(
398 mDevice, templateId, &rawRequest);
399 request->acquire(rawRequest);
400 return err;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700401}
402
403status_t Camera2Device::waitUntilDrained() {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700404 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700405 static const uint32_t kSleepTime = 50000; // 50 ms
406 static const uint32_t kMaxSleepTime = 10000000; // 10 s
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -0700407 ALOGV("%s: Camera %d: Starting wait", __FUNCTION__, mId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700408 if (mRequestQueue.getBufferCount() ==
409 CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS) return INVALID_OPERATION;
410
411 // TODO: Set up notifications from HAL, instead of sleeping here
412 uint32_t totalTime = 0;
413 while (mDevice->ops->get_in_progress_count(mDevice) > 0) {
414 usleep(kSleepTime);
415 totalTime += kSleepTime;
416 if (totalTime > kMaxSleepTime) {
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -0700417 ALOGE("%s: Waited %d us, %d requests still in flight", __FUNCTION__,
418 mDevice->ops->get_in_progress_count(mDevice), totalTime);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700419 return TIMED_OUT;
420 }
421 }
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -0700422 ALOGV("%s: Camera %d: HAL is idle", __FUNCTION__, mId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700423 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700424}
425
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700426status_t Camera2Device::setNotifyCallback(NotificationListener *listener) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700427 ATRACE_CALL();
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700428 status_t res;
429 res = mDevice->ops->set_notify_callback(mDevice, notificationCallback,
430 reinterpret_cast<void*>(listener) );
431 if (res != OK) {
432 ALOGE("%s: Unable to set notification callback!", __FUNCTION__);
433 }
434 return res;
435}
436
437void Camera2Device::notificationCallback(int32_t msg_type,
438 int32_t ext1,
439 int32_t ext2,
440 int32_t ext3,
441 void *user) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700442 ATRACE_CALL();
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700443 NotificationListener *listener = reinterpret_cast<NotificationListener*>(user);
444 ALOGV("%s: Notification %d, arguments %d, %d, %d", __FUNCTION__, msg_type,
445 ext1, ext2, ext3);
446 if (listener != NULL) {
447 switch (msg_type) {
448 case CAMERA2_MSG_ERROR:
449 listener->notifyError(ext1, ext2, ext3);
450 break;
451 case CAMERA2_MSG_SHUTTER: {
452 nsecs_t timestamp = (nsecs_t)ext2 | ((nsecs_t)(ext3) << 32 );
453 listener->notifyShutter(ext1, timestamp);
454 break;
455 }
456 case CAMERA2_MSG_AUTOFOCUS:
457 listener->notifyAutoFocus(ext1, ext2);
458 break;
459 case CAMERA2_MSG_AUTOEXPOSURE:
460 listener->notifyAutoExposure(ext1, ext2);
461 break;
462 case CAMERA2_MSG_AUTOWB:
463 listener->notifyAutoWhitebalance(ext1, ext2);
464 break;
465 default:
466 ALOGE("%s: Unknown notification %d (arguments %d, %d, %d)!",
467 __FUNCTION__, msg_type, ext1, ext2, ext3);
468 }
469 }
470}
471
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -0700472status_t Camera2Device::waitForNextFrame(nsecs_t timeout) {
473 return mFrameQueue.waitForBuffer(timeout);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700474}
475
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700476status_t Camera2Device::getNextFrame(CameraMetadata *frame) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700477 ATRACE_CALL();
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700478 status_t res;
479 camera_metadata_t *rawFrame;
480 res = mFrameQueue.dequeue(&rawFrame);
481 if (rawFrame == NULL) {
482 return NOT_ENOUGH_DATA;
483 } else if (res == OK) {
484 frame->acquire(rawFrame);
485 }
486 return res;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700487}
488
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700489status_t Camera2Device::triggerAutofocus(uint32_t id) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700490 ATRACE_CALL();
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700491 status_t res;
492 ALOGV("%s: Triggering autofocus, id %d", __FUNCTION__, id);
493 res = mDevice->ops->trigger_action(mDevice,
494 CAMERA2_TRIGGER_AUTOFOCUS, id, 0);
495 if (res != OK) {
496 ALOGE("%s: Error triggering autofocus (id %d)",
497 __FUNCTION__, id);
498 }
499 return res;
500}
501
502status_t Camera2Device::triggerCancelAutofocus(uint32_t id) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700503 ATRACE_CALL();
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700504 status_t res;
505 ALOGV("%s: Canceling autofocus, id %d", __FUNCTION__, id);
506 res = mDevice->ops->trigger_action(mDevice,
507 CAMERA2_TRIGGER_CANCEL_AUTOFOCUS, id, 0);
508 if (res != OK) {
509 ALOGE("%s: Error canceling autofocus (id %d)",
510 __FUNCTION__, id);
511 }
512 return res;
513}
514
515status_t Camera2Device::triggerPrecaptureMetering(uint32_t id) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700516 ATRACE_CALL();
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700517 status_t res;
518 ALOGV("%s: Triggering precapture metering, id %d", __FUNCTION__, id);
519 res = mDevice->ops->trigger_action(mDevice,
520 CAMERA2_TRIGGER_PRECAPTURE_METERING, id, 0);
521 if (res != OK) {
522 ALOGE("%s: Error triggering precapture metering (id %d)",
523 __FUNCTION__, id);
524 }
525 return res;
526}
527
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700528status_t Camera2Device::pushReprocessBuffer(int reprocessStreamId,
529 buffer_handle_t *buffer, wp<BufferReleasedListener> listener) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700530 ATRACE_CALL();
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700531 ALOGV("%s: E", __FUNCTION__);
532 bool found = false;
533 status_t res = OK;
534 for (ReprocessStreamList::iterator streamI = mReprocessStreams.begin();
535 streamI != mReprocessStreams.end(); streamI++) {
536 if ((*streamI)->getId() == reprocessStreamId) {
537 res = (*streamI)->pushIntoStream(buffer, listener);
538 if (res != OK) {
539 ALOGE("%s: Unable to push buffer to reprocess stream %d: %s (%d)",
540 __FUNCTION__, reprocessStreamId, strerror(-res), res);
541 return res;
542 }
543 found = true;
544 break;
545 }
546 }
547 if (!found) {
548 ALOGE("%s: Camera %d: Unable to find reprocess stream %d",
549 __FUNCTION__, mId, reprocessStreamId);
550 res = BAD_VALUE;
551 }
552 return res;
553}
554
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700555/**
556 * Camera2Device::NotificationListener
557 */
558
559Camera2Device::NotificationListener::~NotificationListener() {
560}
561
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700562/**
563 * Camera2Device::MetadataQueue
564 */
565
566Camera2Device::MetadataQueue::MetadataQueue():
567 mDevice(NULL),
568 mFrameCount(0),
569 mCount(0),
570 mStreamSlotCount(0),
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -0700571 mSignalConsumer(true)
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700572{
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700573 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700574 camera2_request_queue_src_ops::dequeue_request = consumer_dequeue;
575 camera2_request_queue_src_ops::request_count = consumer_buffer_count;
576 camera2_request_queue_src_ops::free_request = consumer_free;
577
578 camera2_frame_queue_dst_ops::dequeue_frame = producer_dequeue;
579 camera2_frame_queue_dst_ops::cancel_frame = producer_cancel;
580 camera2_frame_queue_dst_ops::enqueue_frame = producer_enqueue;
581}
582
583Camera2Device::MetadataQueue::~MetadataQueue() {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700584 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700585 Mutex::Autolock l(mMutex);
586 freeBuffers(mEntries.begin(), mEntries.end());
587 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
588}
589
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700590// Connect to camera2 HAL as consumer (input requests/reprocessing)
591status_t Camera2Device::MetadataQueue::setConsumerDevice(camera2_device_t *d) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700592 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700593 status_t res;
594 res = d->ops->set_request_queue_src_ops(d,
595 this);
596 if (res != OK) return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700597 mDevice = d;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700598 return OK;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700599}
600
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700601status_t Camera2Device::MetadataQueue::setProducerDevice(camera2_device_t *d) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700602 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700603 status_t res;
604 res = d->ops->set_frame_queue_dst_ops(d,
605 this);
606 return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700607}
608
609// Real interfaces
610status_t Camera2Device::MetadataQueue::enqueue(camera_metadata_t *buf) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700611 ATRACE_CALL();
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700612 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700613 Mutex::Autolock l(mMutex);
614
615 mCount++;
616 mEntries.push_back(buf);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700617
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700618 return signalConsumerLocked();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700619}
620
621int Camera2Device::MetadataQueue::getBufferCount() {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700622 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700623 Mutex::Autolock l(mMutex);
624 if (mStreamSlotCount > 0) {
625 return CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS;
626 }
627 return mCount;
628}
629
630status_t Camera2Device::MetadataQueue::dequeue(camera_metadata_t **buf,
631 bool incrementCount)
632{
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700633 ATRACE_CALL();
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700634 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700635 status_t res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700636 Mutex::Autolock l(mMutex);
637
638 if (mCount == 0) {
639 if (mStreamSlotCount == 0) {
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700640 ALOGVV("%s: Empty", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700641 *buf = NULL;
642 mSignalConsumer = true;
643 return OK;
644 }
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700645 ALOGVV("%s: Streaming %d frames to queue", __FUNCTION__,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700646 mStreamSlotCount);
647
648 for (List<camera_metadata_t*>::iterator slotEntry = mStreamSlot.begin();
649 slotEntry != mStreamSlot.end();
650 slotEntry++ ) {
651 size_t entries = get_camera_metadata_entry_count(*slotEntry);
652 size_t dataBytes = get_camera_metadata_data_count(*slotEntry);
653
654 camera_metadata_t *copy =
655 allocate_camera_metadata(entries, dataBytes);
656 append_camera_metadata(copy, *slotEntry);
657 mEntries.push_back(copy);
658 }
659 mCount = mStreamSlotCount;
660 }
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700661 ALOGVV("MetadataQueue: deque (%d buffers)", mCount);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700662 camera_metadata_t *b = *(mEntries.begin());
663 mEntries.erase(mEntries.begin());
664
665 if (incrementCount) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700666 ATRACE_INT("cam2_request", mFrameCount);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700667 camera_metadata_entry_t frameCount;
668 res = find_camera_metadata_entry(b,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700669 ANDROID_REQUEST_FRAME_COUNT,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700670 &frameCount);
671 if (res != OK) {
672 ALOGE("%s: Unable to add frame count: %s (%d)",
673 __FUNCTION__, strerror(-res), res);
674 } else {
675 *frameCount.data.i32 = mFrameCount;
676 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700677 mFrameCount++;
678 }
679
680 *buf = b;
681 mCount--;
682
683 return OK;
684}
685
686status_t Camera2Device::MetadataQueue::waitForBuffer(nsecs_t timeout)
687{
688 Mutex::Autolock l(mMutex);
689 status_t res;
690 while (mCount == 0) {
691 res = notEmpty.waitRelative(mMutex,timeout);
692 if (res != OK) return res;
693 }
694 return OK;
695}
696
697status_t Camera2Device::MetadataQueue::setStreamSlot(camera_metadata_t *buf)
698{
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700699 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700700 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700701 Mutex::Autolock l(mMutex);
702 if (buf == NULL) {
703 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
704 mStreamSlotCount = 0;
705 return OK;
706 }
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700707 camera_metadata_t *buf2 = clone_camera_metadata(buf);
708 if (!buf2) {
709 ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__);
710 return NO_MEMORY;
711 }
712
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700713 if (mStreamSlotCount > 1) {
714 List<camera_metadata_t*>::iterator deleter = ++mStreamSlot.begin();
715 freeBuffers(++mStreamSlot.begin(), mStreamSlot.end());
716 mStreamSlotCount = 1;
717 }
718 if (mStreamSlotCount == 1) {
719 free_camera_metadata( *(mStreamSlot.begin()) );
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700720 *(mStreamSlot.begin()) = buf2;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700721 } else {
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700722 mStreamSlot.push_front(buf2);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700723 mStreamSlotCount = 1;
724 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700725 return signalConsumerLocked();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700726}
727
728status_t Camera2Device::MetadataQueue::setStreamSlot(
729 const List<camera_metadata_t*> &bufs)
730{
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700731 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700732 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700733 Mutex::Autolock l(mMutex);
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700734 status_t res;
735
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700736 if (mStreamSlotCount > 0) {
737 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
738 }
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700739 mStreamSlotCount = 0;
740 for (List<camera_metadata_t*>::const_iterator r = bufs.begin();
741 r != bufs.end(); r++) {
742 camera_metadata_t *r2 = clone_camera_metadata(*r);
743 if (!r2) {
744 ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__);
745 return NO_MEMORY;
746 }
747 mStreamSlot.push_back(r2);
748 mStreamSlotCount++;
749 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700750 return signalConsumerLocked();
751}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700752
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700753status_t Camera2Device::MetadataQueue::dump(int fd,
754 const Vector<String16>& args) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700755 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700756 String8 result;
757 status_t notLocked;
758 notLocked = mMutex.tryLock();
759 if (notLocked) {
760 result.append(" (Unable to lock queue mutex)\n");
761 }
762 result.appendFormat(" Current frame number: %d\n", mFrameCount);
763 if (mStreamSlotCount == 0) {
764 result.append(" Stream slot: Empty\n");
765 write(fd, result.string(), result.size());
766 } else {
767 result.appendFormat(" Stream slot: %d entries\n",
768 mStreamSlot.size());
769 int i = 0;
770 for (List<camera_metadata_t*>::iterator r = mStreamSlot.begin();
771 r != mStreamSlot.end(); r++) {
772 result = String8::format(" Stream slot buffer %d:\n", i);
773 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700774 dump_indented_camera_metadata(*r, fd, 2, 10);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700775 i++;
776 }
777 }
778 if (mEntries.size() == 0) {
779 result = " Main queue is empty\n";
780 write(fd, result.string(), result.size());
781 } else {
782 result = String8::format(" Main queue has %d entries:\n",
783 mEntries.size());
784 int i = 0;
785 for (List<camera_metadata_t*>::iterator r = mEntries.begin();
786 r != mEntries.end(); r++) {
787 result = String8::format(" Queue entry %d:\n", i);
788 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700789 dump_indented_camera_metadata(*r, fd, 2, 10);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700790 i++;
791 }
792 }
793
794 if (notLocked == 0) {
795 mMutex.unlock();
796 }
797
798 return OK;
799}
800
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700801status_t Camera2Device::MetadataQueue::signalConsumerLocked() {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700802 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700803 status_t res = OK;
804 notEmpty.signal();
805 if (mSignalConsumer && mDevice != NULL) {
806 mSignalConsumer = false;
807
808 mMutex.unlock();
809 ALOGV("%s: Signaling consumer", __FUNCTION__);
810 res = mDevice->ops->notify_request_queue_not_empty(mDevice);
811 mMutex.lock();
812 }
813 return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700814}
815
816status_t Camera2Device::MetadataQueue::freeBuffers(
817 List<camera_metadata_t*>::iterator start,
818 List<camera_metadata_t*>::iterator end)
819{
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700820 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700821 while (start != end) {
822 free_camera_metadata(*start);
823 start = mStreamSlot.erase(start);
824 }
825 return OK;
826}
827
828Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
829 const camera2_request_queue_src_ops_t *q)
830{
831 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
832 return const_cast<MetadataQueue*>(cmq);
833}
834
835Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
836 const camera2_frame_queue_dst_ops_t *q)
837{
838 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
839 return const_cast<MetadataQueue*>(cmq);
840}
841
842int Camera2Device::MetadataQueue::consumer_buffer_count(
843 const camera2_request_queue_src_ops_t *q)
844{
845 MetadataQueue *queue = getInstance(q);
846 return queue->getBufferCount();
847}
848
849int Camera2Device::MetadataQueue::consumer_dequeue(
850 const camera2_request_queue_src_ops_t *q,
851 camera_metadata_t **buffer)
852{
853 MetadataQueue *queue = getInstance(q);
854 return queue->dequeue(buffer, true);
855}
856
857int Camera2Device::MetadataQueue::consumer_free(
858 const camera2_request_queue_src_ops_t *q,
859 camera_metadata_t *old_buffer)
860{
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700861 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700862 MetadataQueue *queue = getInstance(q);
863 free_camera_metadata(old_buffer);
864 return OK;
865}
866
867int Camera2Device::MetadataQueue::producer_dequeue(
868 const camera2_frame_queue_dst_ops_t *q,
869 size_t entries, size_t bytes,
870 camera_metadata_t **buffer)
871{
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700872 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700873 camera_metadata_t *new_buffer =
874 allocate_camera_metadata(entries, bytes);
875 if (new_buffer == NULL) return NO_MEMORY;
876 *buffer = new_buffer;
877 return OK;
878}
879
880int Camera2Device::MetadataQueue::producer_cancel(
881 const camera2_frame_queue_dst_ops_t *q,
882 camera_metadata_t *old_buffer)
883{
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700884 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700885 free_camera_metadata(old_buffer);
886 return OK;
887}
888
889int Camera2Device::MetadataQueue::producer_enqueue(
890 const camera2_frame_queue_dst_ops_t *q,
891 camera_metadata_t *filled_buffer)
892{
893 MetadataQueue *queue = getInstance(q);
894 return queue->enqueue(filled_buffer);
895}
896
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700897/**
898 * Camera2Device::StreamAdapter
899 */
900
901#ifndef container_of
902#define container_of(ptr, type, member) \
903 (type *)((char*)(ptr) - offsetof(type, member))
904#endif
905
906Camera2Device::StreamAdapter::StreamAdapter(camera2_device_t *d):
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700907 mState(RELEASED),
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700908 mDevice(d),
909 mId(-1),
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700910 mWidth(0), mHeight(0), mFormat(0), mSize(0), mUsage(0),
911 mMaxProducerBuffers(0), mMaxConsumerBuffers(0),
912 mTotalBuffers(0),
913 mFormatRequested(0),
914 mActiveBuffers(0),
915 mFrameCount(0),
916 mLastTimestamp(0)
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700917{
918 camera2_stream_ops::dequeue_buffer = dequeue_buffer;
919 camera2_stream_ops::enqueue_buffer = enqueue_buffer;
920 camera2_stream_ops::cancel_buffer = cancel_buffer;
921 camera2_stream_ops::set_crop = set_crop;
922}
923
924Camera2Device::StreamAdapter::~StreamAdapter() {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700925 ATRACE_CALL();
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700926 if (mState != RELEASED) {
927 release();
928 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700929}
930
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700931status_t Camera2Device::StreamAdapter::connectToDevice(
932 sp<ANativeWindow> consumer,
933 uint32_t width, uint32_t height, int format, size_t size) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700934 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700935 status_t res;
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700936 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700937
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700938 if (mState != RELEASED) return INVALID_OPERATION;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700939 if (consumer == NULL) {
940 ALOGE("%s: Null consumer passed to stream adapter", __FUNCTION__);
941 return BAD_VALUE;
942 }
943
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700944 ALOGV("%s: New stream parameters %d x %d, format 0x%x, size %d",
945 __FUNCTION__, width, height, format, size);
946
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700947 mConsumerInterface = consumer;
948 mWidth = width;
949 mHeight = height;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700950 mSize = (format == HAL_PIXEL_FORMAT_BLOB) ? size : 0;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700951 mFormatRequested = format;
952
953 // Allocate device-side stream interface
954
955 uint32_t id;
956 uint32_t formatActual;
957 uint32_t usage;
958 uint32_t maxBuffers = 2;
959 res = mDevice->ops->allocate_stream(mDevice,
960 mWidth, mHeight, mFormatRequested, getStreamOps(),
961 &id, &formatActual, &usage, &maxBuffers);
962 if (res != OK) {
963 ALOGE("%s: Device stream allocation failed: %s (%d)",
964 __FUNCTION__, strerror(-res), res);
965 return res;
966 }
967
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700968 ALOGV("%s: Allocated stream id %d, actual format 0x%x, "
969 "usage 0x%x, producer wants %d buffers", __FUNCTION__,
970 id, formatActual, usage, maxBuffers);
971
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700972 mId = id;
973 mFormat = formatActual;
974 mUsage = usage;
975 mMaxProducerBuffers = maxBuffers;
976
977 mState = ALLOCATED;
978
979 // Configure consumer-side ANativeWindow interface
980 res = native_window_api_connect(mConsumerInterface.get(),
981 NATIVE_WINDOW_API_CAMERA);
982 if (res != OK) {
983 ALOGE("%s: Unable to connect to native window for stream %d",
984 __FUNCTION__, mId);
985
986 return res;
987 }
988
989 mState = CONNECTED;
990
991 res = native_window_set_usage(mConsumerInterface.get(), mUsage);
992 if (res != OK) {
993 ALOGE("%s: Unable to configure usage %08x for stream %d",
994 __FUNCTION__, mUsage, mId);
995 return res;
996 }
997
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -0700998 res = native_window_set_scaling_mode(mConsumerInterface.get(),
999 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
1000 if (res != OK) {
1001 ALOGE("%s: Unable to configure stream scaling: %s (%d)",
1002 __FUNCTION__, strerror(-res), res);
1003 return res;
1004 }
1005
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001006 res = setTransform(0);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001007 if (res != OK) {
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001008 return res;
1009 }
1010
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001011 if (mFormat == HAL_PIXEL_FORMAT_BLOB) {
1012 res = native_window_set_buffers_geometry(mConsumerInterface.get(),
1013 mSize, 1, mFormat);
1014 if (res != OK) {
1015 ALOGE("%s: Unable to configure compressed stream buffer geometry"
1016 " %d x %d, size %d for stream %d",
1017 __FUNCTION__, mWidth, mHeight, mSize, mId);
1018 return res;
1019 }
1020 } else {
1021 res = native_window_set_buffers_geometry(mConsumerInterface.get(),
1022 mWidth, mHeight, mFormat);
1023 if (res != OK) {
1024 ALOGE("%s: Unable to configure stream buffer geometry"
1025 " %d x %d, format 0x%x for stream %d",
1026 __FUNCTION__, mWidth, mHeight, mFormat, mId);
1027 return res;
1028 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001029 }
1030
1031 int maxConsumerBuffers;
1032 res = mConsumerInterface->query(mConsumerInterface.get(),
1033 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &maxConsumerBuffers);
1034 if (res != OK) {
1035 ALOGE("%s: Unable to query consumer undequeued"
1036 " buffer count for stream %d", __FUNCTION__, mId);
1037 return res;
1038 }
1039 mMaxConsumerBuffers = maxConsumerBuffers;
1040
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001041 ALOGV("%s: Consumer wants %d buffers", __FUNCTION__,
1042 mMaxConsumerBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001043
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001044 mTotalBuffers = mMaxConsumerBuffers + mMaxProducerBuffers;
1045 mActiveBuffers = 0;
1046 mFrameCount = 0;
1047 mLastTimestamp = 0;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001048
1049 res = native_window_set_buffer_count(mConsumerInterface.get(),
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001050 mTotalBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001051 if (res != OK) {
1052 ALOGE("%s: Unable to set buffer count for stream %d",
1053 __FUNCTION__, mId);
1054 return res;
1055 }
1056
1057 // Register allocated buffers with HAL device
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001058 buffer_handle_t *buffers = new buffer_handle_t[mTotalBuffers];
1059 ANativeWindowBuffer **anwBuffers = new ANativeWindowBuffer*[mTotalBuffers];
1060 uint32_t bufferIdx = 0;
1061 for (; bufferIdx < mTotalBuffers; bufferIdx++) {
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001062 res = native_window_dequeue_buffer_and_wait(mConsumerInterface.get(),
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001063 &anwBuffers[bufferIdx]);
1064 if (res != OK) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001065 ALOGE("%s: Unable to dequeue buffer %d for initial registration for "
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001066 "stream %d", __FUNCTION__, bufferIdx, mId);
1067 goto cleanUpBuffers;
1068 }
1069
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001070 buffers[bufferIdx] = anwBuffers[bufferIdx]->handle;
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -07001071 ALOGV("%s: Buffer %p allocated", __FUNCTION__, (void*)buffers[bufferIdx]);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001072 }
1073
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001074 ALOGV("%s: Registering %d buffers with camera HAL", __FUNCTION__, mTotalBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001075 res = mDevice->ops->register_stream_buffers(mDevice,
1076 mId,
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001077 mTotalBuffers,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001078 buffers);
1079 if (res != OK) {
1080 ALOGE("%s: Unable to register buffers with HAL device for stream %d",
1081 __FUNCTION__, mId);
1082 } else {
1083 mState = ACTIVE;
1084 }
1085
1086cleanUpBuffers:
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001087 ALOGV("%s: Cleaning up %d buffers", __FUNCTION__, bufferIdx);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001088 for (uint32_t i = 0; i < bufferIdx; i++) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001089 res = mConsumerInterface->cancelBuffer(mConsumerInterface.get(),
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001090 anwBuffers[i], -1);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001091 if (res != OK) {
1092 ALOGE("%s: Unable to cancel buffer %d after registration",
1093 __FUNCTION__, i);
1094 }
1095 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001096 delete[] anwBuffers;
1097 delete[] buffers;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001098
1099 return res;
1100}
1101
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001102status_t Camera2Device::StreamAdapter::release() {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -07001103 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001104 status_t res;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001105 ALOGV("%s: Releasing stream %d", __FUNCTION__, mId);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001106 if (mState >= ALLOCATED) {
1107 res = mDevice->ops->release_stream(mDevice, mId);
1108 if (res != OK) {
1109 ALOGE("%s: Unable to release stream %d",
1110 __FUNCTION__, mId);
1111 return res;
1112 }
1113 }
1114 if (mState >= CONNECTED) {
1115 res = native_window_api_disconnect(mConsumerInterface.get(),
1116 NATIVE_WINDOW_API_CAMERA);
1117 if (res != OK) {
1118 ALOGE("%s: Unable to disconnect stream %d from native window",
1119 __FUNCTION__, mId);
1120 return res;
1121 }
1122 }
1123 mId = -1;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001124 mState = RELEASED;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001125 return OK;
1126}
1127
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001128status_t Camera2Device::StreamAdapter::setTransform(int transform) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -07001129 ATRACE_CALL();
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001130 status_t res;
1131 if (mState < CONNECTED) {
1132 ALOGE("%s: Cannot set transform on unconnected stream", __FUNCTION__);
1133 return INVALID_OPERATION;
1134 }
1135 res = native_window_set_buffers_transform(mConsumerInterface.get(),
1136 transform);
1137 if (res != OK) {
1138 ALOGE("%s: Unable to configure stream transform to %x: %s (%d)",
1139 __FUNCTION__, transform, strerror(-res), res);
1140 }
1141 return res;
1142}
1143
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001144status_t Camera2Device::StreamAdapter::dump(int fd,
1145 const Vector<String16>& args) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -07001146 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001147 String8 result = String8::format(" Stream %d: %d x %d, format 0x%x\n",
1148 mId, mWidth, mHeight, mFormat);
1149 result.appendFormat(" size %d, usage 0x%x, requested format 0x%x\n",
1150 mSize, mUsage, mFormatRequested);
1151 result.appendFormat(" total buffers: %d, dequeued buffers: %d\n",
1152 mTotalBuffers, mActiveBuffers);
1153 result.appendFormat(" frame count: %d, last timestamp %lld\n",
1154 mFrameCount, mLastTimestamp);
1155 write(fd, result.string(), result.size());
1156 return OK;
1157}
1158
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001159const camera2_stream_ops *Camera2Device::StreamAdapter::getStreamOps() {
1160 return static_cast<camera2_stream_ops *>(this);
1161}
1162
1163ANativeWindow* Camera2Device::StreamAdapter::toANW(
1164 const camera2_stream_ops_t *w) {
1165 return static_cast<const StreamAdapter*>(w)->mConsumerInterface.get();
1166}
1167
1168int Camera2Device::StreamAdapter::dequeue_buffer(const camera2_stream_ops_t *w,
1169 buffer_handle_t** buffer) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -07001170 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001171 int res;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001172 StreamAdapter* stream =
1173 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
1174 if (stream->mState != ACTIVE) {
1175 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001176 return INVALID_OPERATION;
1177 }
1178
1179 ANativeWindow *a = toANW(w);
1180 ANativeWindowBuffer* anb;
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001181 res = native_window_dequeue_buffer_and_wait(a, &anb);
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001182 if (res != OK) {
1183 ALOGE("Stream %d dequeue: Error from native_window: %s (%d)", stream->mId,
1184 strerror(-res), res);
1185 return res;
1186 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001187
1188 *buffer = &(anb->handle);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001189 stream->mActiveBuffers++;
1190
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001191 ALOGVV("Stream %d dequeue: Buffer %p dequeued", stream->mId, (void*)(**buffer));
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001192 return res;
1193}
1194
1195int Camera2Device::StreamAdapter::enqueue_buffer(const camera2_stream_ops_t* w,
1196 int64_t timestamp,
1197 buffer_handle_t* buffer) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -07001198 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001199 StreamAdapter *stream =
1200 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001201 stream->mFrameCount++;
1202 ALOGVV("Stream %d enqueue: Frame %d (%p) captured at %lld ns",
James Dong6638f3b2012-09-05 16:46:36 -07001203 stream->mId, stream->mFrameCount, (void*)(*buffer), timestamp);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001204 int state = stream->mState;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001205 if (state != ACTIVE) {
1206 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1207 return INVALID_OPERATION;
1208 }
1209 ANativeWindow *a = toANW(w);
1210 status_t err;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001211
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001212 err = native_window_set_buffers_timestamp(a, timestamp);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001213 if (err != OK) {
1214 ALOGE("%s: Error setting timestamp on native window: %s (%d)",
1215 __FUNCTION__, strerror(-err), err);
1216 return err;
1217 }
1218 err = a->queueBuffer(a,
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001219 container_of(buffer, ANativeWindowBuffer, handle), -1);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001220 if (err != OK) {
1221 ALOGE("%s: Error queueing buffer to native window: %s (%d)",
1222 __FUNCTION__, strerror(-err), err);
James Dong31d377b2012-08-09 17:43:46 -07001223 return err;
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001224 }
James Dong31d377b2012-08-09 17:43:46 -07001225
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001226 stream->mActiveBuffers--;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001227 stream->mLastTimestamp = timestamp;
James Dong31d377b2012-08-09 17:43:46 -07001228 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001229}
1230
1231int Camera2Device::StreamAdapter::cancel_buffer(const camera2_stream_ops_t* w,
1232 buffer_handle_t* buffer) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -07001233 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001234 StreamAdapter *stream =
1235 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001236 ALOGVV("Stream %d cancel: Buffer %p",
1237 stream->mId, (void*)(*buffer));
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001238 if (stream->mState != ACTIVE) {
1239 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001240 return INVALID_OPERATION;
1241 }
James Dong31d377b2012-08-09 17:43:46 -07001242
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001243 ANativeWindow *a = toANW(w);
James Dong31d377b2012-08-09 17:43:46 -07001244 int err = a->cancelBuffer(a,
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001245 container_of(buffer, ANativeWindowBuffer, handle), -1);
James Dong31d377b2012-08-09 17:43:46 -07001246 if (err != OK) {
1247 ALOGE("%s: Error canceling buffer to native window: %s (%d)",
1248 __FUNCTION__, strerror(-err), err);
1249 return err;
1250 }
1251
1252 stream->mActiveBuffers--;
1253 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001254}
1255
1256int Camera2Device::StreamAdapter::set_crop(const camera2_stream_ops_t* w,
1257 int left, int top, int right, int bottom) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -07001258 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001259 int state = static_cast<const StreamAdapter*>(w)->mState;
1260 if (state != ACTIVE) {
1261 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1262 return INVALID_OPERATION;
1263 }
1264 ANativeWindow *a = toANW(w);
1265 android_native_rect_t crop = { left, top, right, bottom };
1266 return native_window_set_crop(a, &crop);
1267}
1268
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -07001269/**
1270 * Camera2Device::ReprocessStreamAdapter
1271 */
1272
1273#ifndef container_of
1274#define container_of(ptr, type, member) \
1275 (type *)((char*)(ptr) - offsetof(type, member))
1276#endif
1277
1278Camera2Device::ReprocessStreamAdapter::ReprocessStreamAdapter(camera2_device_t *d):
1279 mState(RELEASED),
1280 mDevice(d),
1281 mId(-1),
1282 mWidth(0), mHeight(0), mFormat(0),
1283 mActiveBuffers(0),
1284 mFrameCount(0)
1285{
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -07001286 ATRACE_CALL();
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -07001287 camera2_stream_in_ops::acquire_buffer = acquire_buffer;
1288 camera2_stream_in_ops::release_buffer = release_buffer;
1289}
1290
1291Camera2Device::ReprocessStreamAdapter::~ReprocessStreamAdapter() {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -07001292 ATRACE_CALL();
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -07001293 if (mState != RELEASED) {
1294 release();
1295 }
1296}
1297
1298status_t Camera2Device::ReprocessStreamAdapter::connectToDevice(
1299 const sp<StreamAdapter> &outputStream) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -07001300 ATRACE_CALL();
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -07001301 status_t res;
1302 ALOGV("%s: E", __FUNCTION__);
1303
1304 if (mState != RELEASED) return INVALID_OPERATION;
1305 if (outputStream == NULL) {
1306 ALOGE("%s: Null base stream passed to reprocess stream adapter",
1307 __FUNCTION__);
1308 return BAD_VALUE;
1309 }
1310
1311 mBaseStream = outputStream;
1312 mWidth = outputStream->getWidth();
1313 mHeight = outputStream->getHeight();
1314 mFormat = outputStream->getFormat();
1315
1316 ALOGV("%s: New reprocess stream parameters %d x %d, format 0x%x",
1317 __FUNCTION__, mWidth, mHeight, mFormat);
1318
1319 // Allocate device-side stream interface
1320
1321 uint32_t id;
1322 res = mDevice->ops->allocate_reprocess_stream_from_stream(mDevice,
1323 outputStream->getId(), getStreamOps(),
1324 &id);
1325 if (res != OK) {
1326 ALOGE("%s: Device reprocess stream allocation failed: %s (%d)",
1327 __FUNCTION__, strerror(-res), res);
1328 return res;
1329 }
1330
1331 ALOGV("%s: Allocated reprocess stream id %d based on stream %d",
1332 __FUNCTION__, id, outputStream->getId());
1333
1334 mId = id;
1335
1336 mState = ACTIVE;
1337
1338 return OK;
1339}
1340
1341status_t Camera2Device::ReprocessStreamAdapter::release() {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -07001342 ATRACE_CALL();
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -07001343 status_t res;
1344 ALOGV("%s: Releasing stream %d", __FUNCTION__, mId);
1345 if (mState >= ACTIVE) {
1346 res = mDevice->ops->release_reprocess_stream(mDevice, mId);
1347 if (res != OK) {
1348 ALOGE("%s: Unable to release stream %d",
1349 __FUNCTION__, mId);
1350 return res;
1351 }
1352 }
1353
1354 List<QueueEntry>::iterator s;
1355 for (s = mQueue.begin(); s != mQueue.end(); s++) {
1356 sp<BufferReleasedListener> listener = s->releaseListener.promote();
1357 if (listener != 0) listener->onBufferReleased(s->handle);
1358 }
1359 for (s = mInFlightQueue.begin(); s != mInFlightQueue.end(); s++) {
1360 sp<BufferReleasedListener> listener = s->releaseListener.promote();
1361 if (listener != 0) listener->onBufferReleased(s->handle);
1362 }
1363 mQueue.clear();
1364 mInFlightQueue.clear();
1365
1366 mState = RELEASED;
1367 return OK;
1368}
1369
1370status_t Camera2Device::ReprocessStreamAdapter::pushIntoStream(
1371 buffer_handle_t *handle, const wp<BufferReleasedListener> &releaseListener) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -07001372 ATRACE_CALL();
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -07001373 // TODO: Some error checking here would be nice
1374 ALOGV("%s: Pushing buffer %p to stream", __FUNCTION__, (void*)(*handle));
1375
1376 QueueEntry entry;
1377 entry.handle = handle;
1378 entry.releaseListener = releaseListener;
1379 mQueue.push_back(entry);
1380 return OK;
1381}
1382
1383status_t Camera2Device::ReprocessStreamAdapter::dump(int fd,
1384 const Vector<String16>& args) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -07001385 ATRACE_CALL();
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -07001386 String8 result =
1387 String8::format(" Reprocess stream %d: %d x %d, fmt 0x%x\n",
1388 mId, mWidth, mHeight, mFormat);
1389 result.appendFormat(" acquired buffers: %d\n",
1390 mActiveBuffers);
1391 result.appendFormat(" frame count: %d\n",
1392 mFrameCount);
1393 write(fd, result.string(), result.size());
1394 return OK;
1395}
1396
1397const camera2_stream_in_ops *Camera2Device::ReprocessStreamAdapter::getStreamOps() {
1398 return static_cast<camera2_stream_in_ops *>(this);
1399}
1400
1401int Camera2Device::ReprocessStreamAdapter::acquire_buffer(
1402 const camera2_stream_in_ops_t *w,
1403 buffer_handle_t** buffer) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -07001404 ATRACE_CALL();
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -07001405 int res;
1406 ReprocessStreamAdapter* stream =
1407 const_cast<ReprocessStreamAdapter*>(
1408 static_cast<const ReprocessStreamAdapter*>(w));
1409 if (stream->mState != ACTIVE) {
1410 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
1411 return INVALID_OPERATION;
1412 }
1413
1414 if (stream->mQueue.empty()) {
1415 *buffer = NULL;
1416 return OK;
1417 }
1418
1419 QueueEntry &entry = *(stream->mQueue.begin());
1420
1421 *buffer = entry.handle;
1422
1423 stream->mInFlightQueue.push_back(entry);
1424 stream->mQueue.erase(stream->mQueue.begin());
1425
1426 stream->mActiveBuffers++;
1427
1428 ALOGV("Stream %d acquire: Buffer %p acquired", stream->mId,
1429 (void*)(**buffer));
1430 return OK;
1431}
1432
1433int Camera2Device::ReprocessStreamAdapter::release_buffer(
1434 const camera2_stream_in_ops_t* w,
1435 buffer_handle_t* buffer) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -07001436 ATRACE_CALL();
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -07001437 ReprocessStreamAdapter *stream =
1438 const_cast<ReprocessStreamAdapter*>(
1439 static_cast<const ReprocessStreamAdapter*>(w) );
1440 stream->mFrameCount++;
1441 ALOGV("Reprocess stream %d release: Frame %d (%p)",
1442 stream->mId, stream->mFrameCount, (void*)*buffer);
1443 int state = stream->mState;
1444 if (state != ACTIVE) {
1445 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1446 return INVALID_OPERATION;
1447 }
1448 stream->mActiveBuffers--;
1449
1450 List<QueueEntry>::iterator s;
1451 for (s = stream->mInFlightQueue.begin(); s != stream->mInFlightQueue.end(); s++) {
1452 if ( s->handle == buffer ) break;
1453 }
1454 if (s == stream->mInFlightQueue.end()) {
1455 ALOGE("%s: Can't find buffer %p in in-flight list!", __FUNCTION__,
1456 buffer);
1457 return INVALID_OPERATION;
1458 }
1459
1460 sp<BufferReleasedListener> listener = s->releaseListener.promote();
1461 if (listener != 0) {
1462 listener->onBufferReleased(s->handle);
1463 } else {
1464 ALOGE("%s: Can't free buffer - missing listener", __FUNCTION__);
1465 }
1466 stream->mInFlightQueue.erase(s);
1467
1468 return OK;
1469}
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001470
1471}; // namespace android