blob: 81e58cad65ec5d71bd083cfb5d34a9341b855089 [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 Talvala4865c522012-10-02 13:30:28 -070030#include <utils/Timers.h>
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070031#include "Camera2Device.h"
32
33namespace android {
34
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070035Camera2Device::Camera2Device(int id):
36 mId(id),
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -080037 mHal2Device(NULL)
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070038{
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -070039 ATRACE_CALL();
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -070040 ALOGV("%s: Created device for camera %d", __FUNCTION__, id);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070041}
42
43Camera2Device::~Camera2Device()
44{
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -070045 ATRACE_CALL();
Igor Murashkinecf17e82012-10-02 16:05:11 -070046 ALOGV("%s: Tearing down for camera id %d", __FUNCTION__, mId);
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -070047 disconnect();
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070048}
49
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070050status_t Camera2Device::initialize(camera_module_t *module)
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070051{
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -070052 ATRACE_CALL();
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -070053 ALOGV("%s: Initializing device for camera %d", __FUNCTION__, mId);
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -080054 if (mHal2Device != NULL) {
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -070055 ALOGE("%s: Already initialized!", __FUNCTION__);
56 return INVALID_OPERATION;
57 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -070058
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070059 status_t res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070060 char name[10];
61 snprintf(name, sizeof(name), "%d", mId);
62
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -070063 camera2_device_t *device;
64
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070065 res = module->common.methods->open(&module->common, name,
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -070066 reinterpret_cast<hw_device_t**>(&device));
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070067
68 if (res != OK) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070069 ALOGE("%s: Could not open camera %d: %s (%d)", __FUNCTION__,
70 mId, strerror(-res), res);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070071 return res;
72 }
73
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -070074 if (device->common.version != CAMERA_DEVICE_API_VERSION_2_0) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070075 ALOGE("%s: Could not open camera %d: "
76 "Camera device is not version %x, reports %x instead",
77 __FUNCTION__, mId, CAMERA_DEVICE_API_VERSION_2_0,
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -070078 device->common.version);
79 device->common.close(&device->common);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070080 return BAD_VALUE;
81 }
82
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070083 camera_info info;
84 res = module->get_camera_info(mId, &info);
85 if (res != OK ) return res;
86
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -070087 if (info.device_version != device->common.version) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070088 ALOGE("%s: HAL reporting mismatched camera_info version (%x)"
89 " and device version (%x).", __FUNCTION__,
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -070090 device->common.version, info.device_version);
91 device->common.close(&device->common);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070092 return BAD_VALUE;
93 }
94
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -070095 res = mRequestQueue.setConsumerDevice(device);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -070096 if (res != OK) {
97 ALOGE("%s: Camera %d: Unable to connect request queue to device: %s (%d)",
98 __FUNCTION__, mId, strerror(-res), res);
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -070099 device->common.close(&device->common);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700100 return res;
101 }
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -0700102 res = mFrameQueue.setProducerDevice(device);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700103 if (res != OK) {
104 ALOGE("%s: Camera %d: Unable to connect frame queue to device: %s (%d)",
105 __FUNCTION__, mId, strerror(-res), res);
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -0700106 device->common.close(&device->common);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700107 return res;
108 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700109
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -0700110 res = device->ops->get_metadata_vendor_tag_ops(device, &mVendorTagOps);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700111 if (res != OK ) {
112 ALOGE("%s: Camera %d: Unable to retrieve tag ops from device: %s (%d)",
113 __FUNCTION__, mId, strerror(-res), res);
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -0700114 device->common.close(&device->common);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700115 return res;
116 }
Shuzhen Wang092fe442012-08-31 10:24:22 -0700117 res = set_camera_metadata_vendor_tag_ops(mVendorTagOps);
118 if (res != OK) {
119 ALOGE("%s: Camera %d: Unable to set tag ops: %s (%d)",
120 __FUNCTION__, mId, strerror(-res), res);
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -0700121 device->common.close(&device->common);
Shuzhen Wang092fe442012-08-31 10:24:22 -0700122 return res;
123 }
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -0700124 res = device->ops->set_notify_callback(device, notificationCallback,
125 NULL);
126 if (res != OK) {
127 ALOGE("%s: Camera %d: Unable to initialize notification callback!",
128 __FUNCTION__, mId);
129 device->common.close(&device->common);
130 return res;
131 }
132
133 mDeviceInfo = info.static_camera_characteristics;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800134 mHal2Device = device;
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700135
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700136 return OK;
137}
138
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -0700139status_t Camera2Device::disconnect() {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700140 ATRACE_CALL();
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -0700141 status_t res = OK;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800142 if (mHal2Device) {
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -0700143 ALOGV("%s: Closing device for camera %d", __FUNCTION__, mId);
144
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800145 int inProgressCount = mHal2Device->ops->get_in_progress_count(mHal2Device);
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -0700146 if (inProgressCount > 0) {
147 ALOGW("%s: Closing camera device %d with %d requests in flight!",
148 __FUNCTION__, mId, inProgressCount);
149 }
Eino-Ville Talvalac7d9afd2012-09-24 13:44:07 -0700150 mReprocessStreams.clear();
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -0700151 mStreams.clear();
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800152 res = mHal2Device->common.close(&mHal2Device->common);
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -0700153 if (res != OK) {
154 ALOGE("%s: Could not close camera %d: %s (%d)",
155 __FUNCTION__,
156 mId, strerror(-res), res);
157 }
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800158 mHal2Device = NULL;
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -0700159 ALOGV("%s: Shutdown complete", __FUNCTION__);
160 }
161 return res;
162}
163
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700164status_t Camera2Device::dump(int fd, const Vector<String16>& args) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700165 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700166 String8 result;
Eino-Ville Talvala97197152012-08-06 14:25:19 -0700167 int detailLevel = 0;
168 int n = args.size();
169 String16 detailOption("-d");
170 for (int i = 0; i + 1 < n; i++) {
171 if (args[i] == detailOption) {
172 String8 levelStr(args[i+1]);
173 detailLevel = atoi(levelStr.string());
174 }
175 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700176
Eino-Ville Talvala603b12e2012-08-08 09:25:58 -0700177 result.appendFormat(" Camera2Device[%d] dump (detail level %d):\n",
178 mId, detailLevel);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700179
Eino-Ville Talvala97197152012-08-06 14:25:19 -0700180 if (detailLevel > 0) {
181 result = " Request queue contents:\n";
182 write(fd, result.string(), result.size());
183 mRequestQueue.dump(fd, args);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700184
Eino-Ville Talvala97197152012-08-06 14:25:19 -0700185 result = " Frame queue contents:\n";
186 write(fd, result.string(), result.size());
187 mFrameQueue.dump(fd, args);
188 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700189
190 result = " Active streams:\n";
191 write(fd, result.string(), result.size());
192 for (StreamList::iterator s = mStreams.begin(); s != mStreams.end(); s++) {
193 (*s)->dump(fd, args);
194 }
195
196 result = " HAL device dump:\n";
197 write(fd, result.string(), result.size());
198
199 status_t res;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800200 res = mHal2Device->ops->dump(mHal2Device, fd);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700201
202 return res;
203}
204
Igor Murashkin7efa5202013-02-13 15:53:56 -0800205const CameraMetadata& Camera2Device::info() const {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700206 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700207
208 return mDeviceInfo;
209}
210
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700211status_t Camera2Device::capture(CameraMetadata &request) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700212 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700213 ALOGV("%s: E", __FUNCTION__);
214
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700215 mRequestQueue.enqueue(request.release());
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700216 return OK;
217}
218
219
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700220status_t Camera2Device::setStreamingRequest(const CameraMetadata &request) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700221 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700222 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700223 CameraMetadata streamRequest(request);
224 return mRequestQueue.setStreamSlot(streamRequest.release());
225}
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700226
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700227status_t Camera2Device::clearStreamingRequest() {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700228 ATRACE_CALL();
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700229 return mRequestQueue.setStreamSlot(NULL);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700230}
231
Eino-Ville Talvala4865c522012-10-02 13:30:28 -0700232status_t Camera2Device::waitUntilRequestReceived(int32_t requestId, nsecs_t timeout) {
233 ATRACE_CALL();
234 return mRequestQueue.waitForDequeue(requestId, timeout);
235}
236
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700237status_t Camera2Device::createStream(sp<ANativeWindow> consumer,
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700238 uint32_t width, uint32_t height, int format, size_t size, int *id) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700239 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700240 status_t res;
241 ALOGV("%s: E", __FUNCTION__);
242
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800243 sp<StreamAdapter> stream = new StreamAdapter(mHal2Device);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700244
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700245 res = stream->connectToDevice(consumer, width, height, format, size);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700246 if (res != OK) {
247 ALOGE("%s: Camera %d: Unable to create stream (%d x %d, format %x):"
248 "%s (%d)",
249 __FUNCTION__, mId, width, height, format, strerror(-res), res);
250 return res;
251 }
252
253 *id = stream->getId();
254
255 mStreams.push_back(stream);
256 return OK;
257}
258
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700259status_t Camera2Device::createReprocessStreamFromStream(int outputId, int *id) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700260 ATRACE_CALL();
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700261 status_t res;
262 ALOGV("%s: E", __FUNCTION__);
263
264 bool found = false;
265 StreamList::iterator streamI;
266 for (streamI = mStreams.begin();
267 streamI != mStreams.end(); streamI++) {
268 if ((*streamI)->getId() == outputId) {
269 found = true;
270 break;
271 }
272 }
273 if (!found) {
274 ALOGE("%s: Camera %d: Output stream %d doesn't exist; can't create "
275 "reprocess stream from it!", __FUNCTION__, mId, outputId);
276 return BAD_VALUE;
277 }
278
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800279 sp<ReprocessStreamAdapter> stream = new ReprocessStreamAdapter(mHal2Device);
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700280
281 res = stream->connectToDevice((*streamI));
282 if (res != OK) {
283 ALOGE("%s: Camera %d: Unable to create reprocessing stream from "\
284 "stream %d: %s (%d)", __FUNCTION__, mId, outputId,
285 strerror(-res), res);
286 return res;
287 }
288
289 *id = stream->getId();
290
291 mReprocessStreams.push_back(stream);
292 return OK;
293}
294
295
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700296status_t Camera2Device::getStreamInfo(int id,
297 uint32_t *width, uint32_t *height, uint32_t *format) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700298 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700299 ALOGV("%s: E", __FUNCTION__);
300 bool found = false;
301 StreamList::iterator streamI;
302 for (streamI = mStreams.begin();
303 streamI != mStreams.end(); streamI++) {
304 if ((*streamI)->getId() == id) {
305 found = true;
306 break;
307 }
308 }
309 if (!found) {
310 ALOGE("%s: Camera %d: Stream %d does not exist",
311 __FUNCTION__, mId, id);
312 return BAD_VALUE;
313 }
314
315 if (width) *width = (*streamI)->getWidth();
316 if (height) *height = (*streamI)->getHeight();
317 if (format) *format = (*streamI)->getFormat();
318
319 return OK;
320}
321
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -0700322status_t Camera2Device::setStreamTransform(int id,
323 int transform) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700324 ATRACE_CALL();
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -0700325 ALOGV("%s: E", __FUNCTION__);
326 bool found = false;
327 StreamList::iterator streamI;
328 for (streamI = mStreams.begin();
329 streamI != mStreams.end(); streamI++) {
330 if ((*streamI)->getId() == id) {
331 found = true;
332 break;
333 }
334 }
335 if (!found) {
336 ALOGE("%s: Camera %d: Stream %d does not exist",
337 __FUNCTION__, mId, id);
338 return BAD_VALUE;
339 }
340
341 return (*streamI)->setTransform(transform);
342}
343
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700344status_t Camera2Device::deleteStream(int id) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700345 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700346 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700347 bool found = false;
348 for (StreamList::iterator streamI = mStreams.begin();
349 streamI != mStreams.end(); streamI++) {
350 if ((*streamI)->getId() == id) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700351 status_t res = (*streamI)->release();
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700352 if (res != OK) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700353 ALOGE("%s: Unable to release stream %d from HAL device: "
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700354 "%s (%d)", __FUNCTION__, id, strerror(-res), res);
355 return res;
356 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700357 mStreams.erase(streamI);
358 found = true;
359 break;
360 }
361 }
362 if (!found) {
363 ALOGE("%s: Camera %d: Unable to find stream %d to delete",
364 __FUNCTION__, mId, id);
365 return BAD_VALUE;
366 }
367 return OK;
368}
369
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700370status_t Camera2Device::deleteReprocessStream(int id) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700371 ATRACE_CALL();
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700372 ALOGV("%s: E", __FUNCTION__);
373 bool found = false;
374 for (ReprocessStreamList::iterator streamI = mReprocessStreams.begin();
375 streamI != mReprocessStreams.end(); streamI++) {
376 if ((*streamI)->getId() == id) {
377 status_t res = (*streamI)->release();
378 if (res != OK) {
379 ALOGE("%s: Unable to release reprocess stream %d from "
380 "HAL device: %s (%d)", __FUNCTION__, id,
381 strerror(-res), res);
382 return res;
383 }
384 mReprocessStreams.erase(streamI);
385 found = true;
386 break;
387 }
388 }
389 if (!found) {
390 ALOGE("%s: Camera %d: Unable to find stream %d to delete",
391 __FUNCTION__, mId, id);
392 return BAD_VALUE;
393 }
394 return OK;
395}
396
397
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700398status_t Camera2Device::createDefaultRequest(int templateId,
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700399 CameraMetadata *request) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700400 ATRACE_CALL();
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700401 status_t err;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700402 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700403 camera_metadata_t *rawRequest;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800404 err = mHal2Device->ops->construct_default_request(
405 mHal2Device, templateId, &rawRequest);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700406 request->acquire(rawRequest);
407 return err;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700408}
409
410status_t Camera2Device::waitUntilDrained() {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700411 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700412 static const uint32_t kSleepTime = 50000; // 50 ms
413 static const uint32_t kMaxSleepTime = 10000000; // 10 s
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -0700414 ALOGV("%s: Camera %d: Starting wait", __FUNCTION__, mId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700415 if (mRequestQueue.getBufferCount() ==
416 CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS) return INVALID_OPERATION;
417
418 // TODO: Set up notifications from HAL, instead of sleeping here
419 uint32_t totalTime = 0;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800420 while (mHal2Device->ops->get_in_progress_count(mHal2Device) > 0) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700421 usleep(kSleepTime);
422 totalTime += kSleepTime;
423 if (totalTime > kMaxSleepTime) {
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -0700424 ALOGE("%s: Waited %d us, %d requests still in flight", __FUNCTION__,
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800425 mHal2Device->ops->get_in_progress_count(mHal2Device), totalTime);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700426 return TIMED_OUT;
427 }
428 }
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -0700429 ALOGV("%s: Camera %d: HAL is idle", __FUNCTION__, mId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700430 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700431}
432
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700433status_t Camera2Device::setNotifyCallback(NotificationListener *listener) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700434 ATRACE_CALL();
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700435 status_t res;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800436 res = mHal2Device->ops->set_notify_callback(mHal2Device, notificationCallback,
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700437 reinterpret_cast<void*>(listener) );
438 if (res != OK) {
439 ALOGE("%s: Unable to set notification callback!", __FUNCTION__);
440 }
441 return res;
442}
443
444void Camera2Device::notificationCallback(int32_t msg_type,
445 int32_t ext1,
446 int32_t ext2,
447 int32_t ext3,
448 void *user) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700449 ATRACE_CALL();
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700450 NotificationListener *listener = reinterpret_cast<NotificationListener*>(user);
451 ALOGV("%s: Notification %d, arguments %d, %d, %d", __FUNCTION__, msg_type,
452 ext1, ext2, ext3);
453 if (listener != NULL) {
454 switch (msg_type) {
455 case CAMERA2_MSG_ERROR:
456 listener->notifyError(ext1, ext2, ext3);
457 break;
458 case CAMERA2_MSG_SHUTTER: {
459 nsecs_t timestamp = (nsecs_t)ext2 | ((nsecs_t)(ext3) << 32 );
460 listener->notifyShutter(ext1, timestamp);
461 break;
462 }
463 case CAMERA2_MSG_AUTOFOCUS:
464 listener->notifyAutoFocus(ext1, ext2);
465 break;
466 case CAMERA2_MSG_AUTOEXPOSURE:
467 listener->notifyAutoExposure(ext1, ext2);
468 break;
469 case CAMERA2_MSG_AUTOWB:
470 listener->notifyAutoWhitebalance(ext1, ext2);
471 break;
472 default:
473 ALOGE("%s: Unknown notification %d (arguments %d, %d, %d)!",
474 __FUNCTION__, msg_type, ext1, ext2, ext3);
475 }
476 }
477}
478
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -0700479status_t Camera2Device::waitForNextFrame(nsecs_t timeout) {
480 return mFrameQueue.waitForBuffer(timeout);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700481}
482
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700483status_t Camera2Device::getNextFrame(CameraMetadata *frame) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700484 ATRACE_CALL();
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700485 status_t res;
486 camera_metadata_t *rawFrame;
487 res = mFrameQueue.dequeue(&rawFrame);
488 if (rawFrame == NULL) {
489 return NOT_ENOUGH_DATA;
490 } else if (res == OK) {
491 frame->acquire(rawFrame);
492 }
493 return res;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700494}
495
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700496status_t Camera2Device::triggerAutofocus(uint32_t id) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700497 ATRACE_CALL();
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700498 status_t res;
499 ALOGV("%s: Triggering autofocus, id %d", __FUNCTION__, id);
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800500 res = mHal2Device->ops->trigger_action(mHal2Device,
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700501 CAMERA2_TRIGGER_AUTOFOCUS, id, 0);
502 if (res != OK) {
503 ALOGE("%s: Error triggering autofocus (id %d)",
504 __FUNCTION__, id);
505 }
506 return res;
507}
508
509status_t Camera2Device::triggerCancelAutofocus(uint32_t id) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700510 ATRACE_CALL();
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700511 status_t res;
512 ALOGV("%s: Canceling autofocus, id %d", __FUNCTION__, id);
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800513 res = mHal2Device->ops->trigger_action(mHal2Device,
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700514 CAMERA2_TRIGGER_CANCEL_AUTOFOCUS, id, 0);
515 if (res != OK) {
516 ALOGE("%s: Error canceling autofocus (id %d)",
517 __FUNCTION__, id);
518 }
519 return res;
520}
521
522status_t Camera2Device::triggerPrecaptureMetering(uint32_t id) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700523 ATRACE_CALL();
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700524 status_t res;
525 ALOGV("%s: Triggering precapture metering, id %d", __FUNCTION__, id);
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800526 res = mHal2Device->ops->trigger_action(mHal2Device,
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700527 CAMERA2_TRIGGER_PRECAPTURE_METERING, id, 0);
528 if (res != OK) {
529 ALOGE("%s: Error triggering precapture metering (id %d)",
530 __FUNCTION__, id);
531 }
532 return res;
533}
534
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700535status_t Camera2Device::pushReprocessBuffer(int reprocessStreamId,
536 buffer_handle_t *buffer, wp<BufferReleasedListener> listener) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700537 ATRACE_CALL();
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700538 ALOGV("%s: E", __FUNCTION__);
539 bool found = false;
540 status_t res = OK;
541 for (ReprocessStreamList::iterator streamI = mReprocessStreams.begin();
542 streamI != mReprocessStreams.end(); streamI++) {
543 if ((*streamI)->getId() == reprocessStreamId) {
544 res = (*streamI)->pushIntoStream(buffer, listener);
545 if (res != OK) {
546 ALOGE("%s: Unable to push buffer to reprocess stream %d: %s (%d)",
547 __FUNCTION__, reprocessStreamId, strerror(-res), res);
548 return res;
549 }
550 found = true;
551 break;
552 }
553 }
554 if (!found) {
555 ALOGE("%s: Camera %d: Unable to find reprocess stream %d",
556 __FUNCTION__, mId, reprocessStreamId);
557 res = BAD_VALUE;
558 }
559 return res;
560}
561
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700562/**
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700563 * Camera2Device::MetadataQueue
564 */
565
566Camera2Device::MetadataQueue::MetadataQueue():
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800567 mHal2Device(NULL),
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700568 mFrameCount(0),
Eino-Ville Talvala4865c522012-10-02 13:30:28 -0700569 mLatestRequestId(0),
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700570 mCount(0),
571 mStreamSlotCount(0),
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -0700572 mSignalConsumer(true)
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700573{
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700574 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700575 camera2_request_queue_src_ops::dequeue_request = consumer_dequeue;
576 camera2_request_queue_src_ops::request_count = consumer_buffer_count;
577 camera2_request_queue_src_ops::free_request = consumer_free;
578
579 camera2_frame_queue_dst_ops::dequeue_frame = producer_dequeue;
580 camera2_frame_queue_dst_ops::cancel_frame = producer_cancel;
581 camera2_frame_queue_dst_ops::enqueue_frame = producer_enqueue;
582}
583
584Camera2Device::MetadataQueue::~MetadataQueue() {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700585 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700586 Mutex::Autolock l(mMutex);
587 freeBuffers(mEntries.begin(), mEntries.end());
588 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
589}
590
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700591// Connect to camera2 HAL as consumer (input requests/reprocessing)
592status_t Camera2Device::MetadataQueue::setConsumerDevice(camera2_device_t *d) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700593 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700594 status_t res;
595 res = d->ops->set_request_queue_src_ops(d,
596 this);
597 if (res != OK) return res;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800598 mHal2Device = d;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700599 return OK;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700600}
601
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700602status_t Camera2Device::MetadataQueue::setProducerDevice(camera2_device_t *d) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700603 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700604 status_t res;
605 res = d->ops->set_frame_queue_dst_ops(d,
606 this);
607 return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700608}
609
610// Real interfaces
611status_t Camera2Device::MetadataQueue::enqueue(camera_metadata_t *buf) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700612 ATRACE_CALL();
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700613 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700614 Mutex::Autolock l(mMutex);
615
616 mCount++;
617 mEntries.push_back(buf);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700618
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700619 return signalConsumerLocked();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700620}
621
622int Camera2Device::MetadataQueue::getBufferCount() {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700623 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700624 Mutex::Autolock l(mMutex);
625 if (mStreamSlotCount > 0) {
626 return CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS;
627 }
628 return mCount;
629}
630
631status_t Camera2Device::MetadataQueue::dequeue(camera_metadata_t **buf,
632 bool incrementCount)
633{
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700634 ATRACE_CALL();
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700635 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700636 status_t res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700637 Mutex::Autolock l(mMutex);
638
639 if (mCount == 0) {
640 if (mStreamSlotCount == 0) {
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700641 ALOGVV("%s: Empty", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700642 *buf = NULL;
643 mSignalConsumer = true;
644 return OK;
645 }
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700646 ALOGVV("%s: Streaming %d frames to queue", __FUNCTION__,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700647 mStreamSlotCount);
648
649 for (List<camera_metadata_t*>::iterator slotEntry = mStreamSlot.begin();
650 slotEntry != mStreamSlot.end();
651 slotEntry++ ) {
652 size_t entries = get_camera_metadata_entry_count(*slotEntry);
653 size_t dataBytes = get_camera_metadata_data_count(*slotEntry);
654
655 camera_metadata_t *copy =
656 allocate_camera_metadata(entries, dataBytes);
657 append_camera_metadata(copy, *slotEntry);
658 mEntries.push_back(copy);
659 }
660 mCount = mStreamSlotCount;
661 }
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700662 ALOGVV("MetadataQueue: deque (%d buffers)", mCount);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700663 camera_metadata_t *b = *(mEntries.begin());
664 mEntries.erase(mEntries.begin());
665
666 if (incrementCount) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700667 ATRACE_INT("cam2_request", mFrameCount);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700668 camera_metadata_entry_t frameCount;
669 res = find_camera_metadata_entry(b,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700670 ANDROID_REQUEST_FRAME_COUNT,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700671 &frameCount);
672 if (res != OK) {
673 ALOGE("%s: Unable to add frame count: %s (%d)",
674 __FUNCTION__, strerror(-res), res);
675 } else {
676 *frameCount.data.i32 = mFrameCount;
677 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700678 mFrameCount++;
679 }
680
Eino-Ville Talvala4865c522012-10-02 13:30:28 -0700681 // Check for request ID, and if present, signal waiters.
682 camera_metadata_entry_t requestId;
683 res = find_camera_metadata_entry(b,
684 ANDROID_REQUEST_ID,
685 &requestId);
686 if (res == OK) {
687 mLatestRequestId = requestId.data.i32[0];
688 mNewRequestId.signal();
689 }
690
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700691 *buf = b;
692 mCount--;
693
694 return OK;
695}
696
697status_t Camera2Device::MetadataQueue::waitForBuffer(nsecs_t timeout)
698{
699 Mutex::Autolock l(mMutex);
700 status_t res;
701 while (mCount == 0) {
702 res = notEmpty.waitRelative(mMutex,timeout);
703 if (res != OK) return res;
704 }
705 return OK;
706}
707
Eino-Ville Talvala4865c522012-10-02 13:30:28 -0700708status_t Camera2Device::MetadataQueue::waitForDequeue(int32_t id,
709 nsecs_t timeout) {
710 Mutex::Autolock l(mMutex);
711 status_t res;
712 while (mLatestRequestId != id) {
713 nsecs_t startTime = systemTime();
714
715 res = mNewRequestId.waitRelative(mMutex, timeout);
716 if (res != OK) return res;
717
718 timeout -= (systemTime() - startTime);
719 }
720
721 return OK;
722}
723
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700724status_t Camera2Device::MetadataQueue::setStreamSlot(camera_metadata_t *buf)
725{
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700726 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700727 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700728 Mutex::Autolock l(mMutex);
729 if (buf == NULL) {
730 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
731 mStreamSlotCount = 0;
732 return OK;
733 }
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700734 camera_metadata_t *buf2 = clone_camera_metadata(buf);
735 if (!buf2) {
736 ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__);
737 return NO_MEMORY;
738 }
739
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700740 if (mStreamSlotCount > 1) {
741 List<camera_metadata_t*>::iterator deleter = ++mStreamSlot.begin();
742 freeBuffers(++mStreamSlot.begin(), mStreamSlot.end());
743 mStreamSlotCount = 1;
744 }
745 if (mStreamSlotCount == 1) {
746 free_camera_metadata( *(mStreamSlot.begin()) );
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700747 *(mStreamSlot.begin()) = buf2;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700748 } else {
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700749 mStreamSlot.push_front(buf2);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700750 mStreamSlotCount = 1;
751 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700752 return signalConsumerLocked();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700753}
754
755status_t Camera2Device::MetadataQueue::setStreamSlot(
756 const List<camera_metadata_t*> &bufs)
757{
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700758 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700759 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700760 Mutex::Autolock l(mMutex);
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700761
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700762 if (mStreamSlotCount > 0) {
763 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
764 }
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700765 mStreamSlotCount = 0;
766 for (List<camera_metadata_t*>::const_iterator r = bufs.begin();
767 r != bufs.end(); r++) {
768 camera_metadata_t *r2 = clone_camera_metadata(*r);
769 if (!r2) {
770 ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__);
771 return NO_MEMORY;
772 }
773 mStreamSlot.push_back(r2);
774 mStreamSlotCount++;
775 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700776 return signalConsumerLocked();
777}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700778
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700779status_t Camera2Device::MetadataQueue::dump(int fd,
Igor Murashkinddf3c502012-10-12 16:56:11 -0700780 const Vector<String16>& /*args*/) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700781 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700782 String8 result;
783 status_t notLocked;
784 notLocked = mMutex.tryLock();
785 if (notLocked) {
786 result.append(" (Unable to lock queue mutex)\n");
787 }
788 result.appendFormat(" Current frame number: %d\n", mFrameCount);
789 if (mStreamSlotCount == 0) {
790 result.append(" Stream slot: Empty\n");
791 write(fd, result.string(), result.size());
792 } else {
793 result.appendFormat(" Stream slot: %d entries\n",
794 mStreamSlot.size());
795 int i = 0;
796 for (List<camera_metadata_t*>::iterator r = mStreamSlot.begin();
797 r != mStreamSlot.end(); r++) {
798 result = String8::format(" Stream slot buffer %d:\n", i);
799 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700800 dump_indented_camera_metadata(*r, fd, 2, 10);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700801 i++;
802 }
803 }
804 if (mEntries.size() == 0) {
805 result = " Main queue is empty\n";
806 write(fd, result.string(), result.size());
807 } else {
808 result = String8::format(" Main queue has %d entries:\n",
809 mEntries.size());
810 int i = 0;
811 for (List<camera_metadata_t*>::iterator r = mEntries.begin();
812 r != mEntries.end(); r++) {
813 result = String8::format(" Queue entry %d:\n", i);
814 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700815 dump_indented_camera_metadata(*r, fd, 2, 10);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700816 i++;
817 }
818 }
819
820 if (notLocked == 0) {
821 mMutex.unlock();
822 }
823
824 return OK;
825}
826
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700827status_t Camera2Device::MetadataQueue::signalConsumerLocked() {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700828 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700829 status_t res = OK;
830 notEmpty.signal();
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800831 if (mSignalConsumer && mHal2Device != NULL) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700832 mSignalConsumer = false;
833
834 mMutex.unlock();
835 ALOGV("%s: Signaling consumer", __FUNCTION__);
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800836 res = mHal2Device->ops->notify_request_queue_not_empty(mHal2Device);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700837 mMutex.lock();
838 }
839 return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700840}
841
842status_t Camera2Device::MetadataQueue::freeBuffers(
843 List<camera_metadata_t*>::iterator start,
844 List<camera_metadata_t*>::iterator end)
845{
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700846 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700847 while (start != end) {
848 free_camera_metadata(*start);
849 start = mStreamSlot.erase(start);
850 }
851 return OK;
852}
853
854Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
855 const camera2_request_queue_src_ops_t *q)
856{
857 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
858 return const_cast<MetadataQueue*>(cmq);
859}
860
861Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
862 const camera2_frame_queue_dst_ops_t *q)
863{
864 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
865 return const_cast<MetadataQueue*>(cmq);
866}
867
868int Camera2Device::MetadataQueue::consumer_buffer_count(
869 const camera2_request_queue_src_ops_t *q)
870{
871 MetadataQueue *queue = getInstance(q);
872 return queue->getBufferCount();
873}
874
875int Camera2Device::MetadataQueue::consumer_dequeue(
876 const camera2_request_queue_src_ops_t *q,
877 camera_metadata_t **buffer)
878{
879 MetadataQueue *queue = getInstance(q);
880 return queue->dequeue(buffer, true);
881}
882
883int Camera2Device::MetadataQueue::consumer_free(
884 const camera2_request_queue_src_ops_t *q,
885 camera_metadata_t *old_buffer)
886{
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700887 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700888 MetadataQueue *queue = getInstance(q);
Igor Murashkinddf3c502012-10-12 16:56:11 -0700889 (void)queue;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700890 free_camera_metadata(old_buffer);
891 return OK;
892}
893
894int Camera2Device::MetadataQueue::producer_dequeue(
Igor Murashkinddf3c502012-10-12 16:56:11 -0700895 const camera2_frame_queue_dst_ops_t * /*q*/,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700896 size_t entries, size_t bytes,
897 camera_metadata_t **buffer)
898{
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700899 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700900 camera_metadata_t *new_buffer =
901 allocate_camera_metadata(entries, bytes);
902 if (new_buffer == NULL) return NO_MEMORY;
903 *buffer = new_buffer;
904 return OK;
905}
906
907int Camera2Device::MetadataQueue::producer_cancel(
Igor Murashkinddf3c502012-10-12 16:56:11 -0700908 const camera2_frame_queue_dst_ops_t * /*q*/,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700909 camera_metadata_t *old_buffer)
910{
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700911 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700912 free_camera_metadata(old_buffer);
913 return OK;
914}
915
916int Camera2Device::MetadataQueue::producer_enqueue(
917 const camera2_frame_queue_dst_ops_t *q,
918 camera_metadata_t *filled_buffer)
919{
920 MetadataQueue *queue = getInstance(q);
921 return queue->enqueue(filled_buffer);
922}
923
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700924/**
925 * Camera2Device::StreamAdapter
926 */
927
928#ifndef container_of
929#define container_of(ptr, type, member) \
930 (type *)((char*)(ptr) - offsetof(type, member))
931#endif
932
933Camera2Device::StreamAdapter::StreamAdapter(camera2_device_t *d):
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700934 mState(RELEASED),
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800935 mHal2Device(d),
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700936 mId(-1),
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700937 mWidth(0), mHeight(0), mFormat(0), mSize(0), mUsage(0),
938 mMaxProducerBuffers(0), mMaxConsumerBuffers(0),
939 mTotalBuffers(0),
940 mFormatRequested(0),
941 mActiveBuffers(0),
942 mFrameCount(0),
943 mLastTimestamp(0)
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700944{
945 camera2_stream_ops::dequeue_buffer = dequeue_buffer;
946 camera2_stream_ops::enqueue_buffer = enqueue_buffer;
947 camera2_stream_ops::cancel_buffer = cancel_buffer;
948 camera2_stream_ops::set_crop = set_crop;
949}
950
951Camera2Device::StreamAdapter::~StreamAdapter() {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700952 ATRACE_CALL();
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700953 if (mState != RELEASED) {
954 release();
955 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700956}
957
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700958status_t Camera2Device::StreamAdapter::connectToDevice(
959 sp<ANativeWindow> consumer,
960 uint32_t width, uint32_t height, int format, size_t size) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700961 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700962 status_t res;
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700963 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700964
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700965 if (mState != RELEASED) return INVALID_OPERATION;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700966 if (consumer == NULL) {
967 ALOGE("%s: Null consumer passed to stream adapter", __FUNCTION__);
968 return BAD_VALUE;
969 }
970
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700971 ALOGV("%s: New stream parameters %d x %d, format 0x%x, size %d",
972 __FUNCTION__, width, height, format, size);
973
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700974 mConsumerInterface = consumer;
975 mWidth = width;
976 mHeight = height;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700977 mSize = (format == HAL_PIXEL_FORMAT_BLOB) ? size : 0;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700978 mFormatRequested = format;
979
980 // Allocate device-side stream interface
981
982 uint32_t id;
983 uint32_t formatActual;
984 uint32_t usage;
985 uint32_t maxBuffers = 2;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800986 res = mHal2Device->ops->allocate_stream(mHal2Device,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700987 mWidth, mHeight, mFormatRequested, getStreamOps(),
988 &id, &formatActual, &usage, &maxBuffers);
989 if (res != OK) {
990 ALOGE("%s: Device stream allocation failed: %s (%d)",
991 __FUNCTION__, strerror(-res), res);
992 return res;
993 }
994
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700995 ALOGV("%s: Allocated stream id %d, actual format 0x%x, "
996 "usage 0x%x, producer wants %d buffers", __FUNCTION__,
997 id, formatActual, usage, maxBuffers);
998
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700999 mId = id;
1000 mFormat = formatActual;
1001 mUsage = usage;
1002 mMaxProducerBuffers = maxBuffers;
1003
1004 mState = ALLOCATED;
1005
1006 // Configure consumer-side ANativeWindow interface
1007 res = native_window_api_connect(mConsumerInterface.get(),
1008 NATIVE_WINDOW_API_CAMERA);
1009 if (res != OK) {
1010 ALOGE("%s: Unable to connect to native window for stream %d",
1011 __FUNCTION__, mId);
1012
1013 return res;
1014 }
1015
1016 mState = CONNECTED;
1017
1018 res = native_window_set_usage(mConsumerInterface.get(), mUsage);
1019 if (res != OK) {
1020 ALOGE("%s: Unable to configure usage %08x for stream %d",
1021 __FUNCTION__, mUsage, mId);
1022 return res;
1023 }
1024
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001025 res = native_window_set_scaling_mode(mConsumerInterface.get(),
1026 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
1027 if (res != OK) {
1028 ALOGE("%s: Unable to configure stream scaling: %s (%d)",
1029 __FUNCTION__, strerror(-res), res);
1030 return res;
1031 }
1032
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001033 res = setTransform(0);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001034 if (res != OK) {
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001035 return res;
1036 }
1037
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001038 if (mFormat == HAL_PIXEL_FORMAT_BLOB) {
1039 res = native_window_set_buffers_geometry(mConsumerInterface.get(),
1040 mSize, 1, mFormat);
1041 if (res != OK) {
1042 ALOGE("%s: Unable to configure compressed stream buffer geometry"
1043 " %d x %d, size %d for stream %d",
1044 __FUNCTION__, mWidth, mHeight, mSize, mId);
1045 return res;
1046 }
1047 } else {
1048 res = native_window_set_buffers_geometry(mConsumerInterface.get(),
1049 mWidth, mHeight, mFormat);
1050 if (res != OK) {
1051 ALOGE("%s: Unable to configure stream buffer geometry"
1052 " %d x %d, format 0x%x for stream %d",
1053 __FUNCTION__, mWidth, mHeight, mFormat, mId);
1054 return res;
1055 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001056 }
1057
1058 int maxConsumerBuffers;
1059 res = mConsumerInterface->query(mConsumerInterface.get(),
1060 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &maxConsumerBuffers);
1061 if (res != OK) {
1062 ALOGE("%s: Unable to query consumer undequeued"
1063 " buffer count for stream %d", __FUNCTION__, mId);
1064 return res;
1065 }
1066 mMaxConsumerBuffers = maxConsumerBuffers;
1067
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001068 ALOGV("%s: Consumer wants %d buffers", __FUNCTION__,
1069 mMaxConsumerBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001070
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001071 mTotalBuffers = mMaxConsumerBuffers + mMaxProducerBuffers;
1072 mActiveBuffers = 0;
1073 mFrameCount = 0;
1074 mLastTimestamp = 0;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001075
1076 res = native_window_set_buffer_count(mConsumerInterface.get(),
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001077 mTotalBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001078 if (res != OK) {
1079 ALOGE("%s: Unable to set buffer count for stream %d",
1080 __FUNCTION__, mId);
1081 return res;
1082 }
1083
1084 // Register allocated buffers with HAL device
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001085 buffer_handle_t *buffers = new buffer_handle_t[mTotalBuffers];
1086 ANativeWindowBuffer **anwBuffers = new ANativeWindowBuffer*[mTotalBuffers];
1087 uint32_t bufferIdx = 0;
1088 for (; bufferIdx < mTotalBuffers; bufferIdx++) {
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001089 res = native_window_dequeue_buffer_and_wait(mConsumerInterface.get(),
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001090 &anwBuffers[bufferIdx]);
1091 if (res != OK) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001092 ALOGE("%s: Unable to dequeue buffer %d for initial registration for "
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001093 "stream %d", __FUNCTION__, bufferIdx, mId);
1094 goto cleanUpBuffers;
1095 }
1096
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001097 buffers[bufferIdx] = anwBuffers[bufferIdx]->handle;
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -07001098 ALOGV("%s: Buffer %p allocated", __FUNCTION__, (void*)buffers[bufferIdx]);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001099 }
1100
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001101 ALOGV("%s: Registering %d buffers with camera HAL", __FUNCTION__, mTotalBuffers);
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -08001102 res = mHal2Device->ops->register_stream_buffers(mHal2Device,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001103 mId,
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001104 mTotalBuffers,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001105 buffers);
1106 if (res != OK) {
1107 ALOGE("%s: Unable to register buffers with HAL device for stream %d",
1108 __FUNCTION__, mId);
1109 } else {
1110 mState = ACTIVE;
1111 }
1112
1113cleanUpBuffers:
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001114 ALOGV("%s: Cleaning up %d buffers", __FUNCTION__, bufferIdx);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001115 for (uint32_t i = 0; i < bufferIdx; i++) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001116 res = mConsumerInterface->cancelBuffer(mConsumerInterface.get(),
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001117 anwBuffers[i], -1);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001118 if (res != OK) {
1119 ALOGE("%s: Unable to cancel buffer %d after registration",
1120 __FUNCTION__, i);
1121 }
1122 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001123 delete[] anwBuffers;
1124 delete[] buffers;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001125
1126 return res;
1127}
1128
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001129status_t Camera2Device::StreamAdapter::release() {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -07001130 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001131 status_t res;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001132 ALOGV("%s: Releasing stream %d", __FUNCTION__, mId);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001133 if (mState >= ALLOCATED) {
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -08001134 res = mHal2Device->ops->release_stream(mHal2Device, mId);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001135 if (res != OK) {
1136 ALOGE("%s: Unable to release stream %d",
1137 __FUNCTION__, mId);
1138 return res;
1139 }
1140 }
1141 if (mState >= CONNECTED) {
1142 res = native_window_api_disconnect(mConsumerInterface.get(),
1143 NATIVE_WINDOW_API_CAMERA);
Igor Murashkinb3e97b32012-10-02 15:21:31 -07001144
1145 /* this is not an error. if client calling process dies,
1146 the window will also die and all calls to it will return
1147 DEAD_OBJECT, thus it's already "disconnected" */
1148 if (res == DEAD_OBJECT) {
1149 ALOGW("%s: While disconnecting stream %d from native window, the"
1150 " native window died from under us", __FUNCTION__, mId);
1151 }
1152 else if (res != OK) {
1153 ALOGE("%s: Unable to disconnect stream %d from native window (error %d %s)",
1154 __FUNCTION__, mId, res, strerror(-res));
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001155 return res;
1156 }
1157 }
1158 mId = -1;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001159 mState = RELEASED;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001160 return OK;
1161}
1162
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001163status_t Camera2Device::StreamAdapter::setTransform(int transform) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -07001164 ATRACE_CALL();
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001165 status_t res;
1166 if (mState < CONNECTED) {
1167 ALOGE("%s: Cannot set transform on unconnected stream", __FUNCTION__);
1168 return INVALID_OPERATION;
1169 }
1170 res = native_window_set_buffers_transform(mConsumerInterface.get(),
1171 transform);
1172 if (res != OK) {
1173 ALOGE("%s: Unable to configure stream transform to %x: %s (%d)",
1174 __FUNCTION__, transform, strerror(-res), res);
1175 }
1176 return res;
1177}
1178
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001179status_t Camera2Device::StreamAdapter::dump(int fd,
Igor Murashkinddf3c502012-10-12 16:56:11 -07001180 const Vector<String16>& /*args*/) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -07001181 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001182 String8 result = String8::format(" Stream %d: %d x %d, format 0x%x\n",
1183 mId, mWidth, mHeight, mFormat);
1184 result.appendFormat(" size %d, usage 0x%x, requested format 0x%x\n",
1185 mSize, mUsage, mFormatRequested);
1186 result.appendFormat(" total buffers: %d, dequeued buffers: %d\n",
1187 mTotalBuffers, mActiveBuffers);
1188 result.appendFormat(" frame count: %d, last timestamp %lld\n",
1189 mFrameCount, mLastTimestamp);
1190 write(fd, result.string(), result.size());
1191 return OK;
1192}
1193
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001194const camera2_stream_ops *Camera2Device::StreamAdapter::getStreamOps() {
1195 return static_cast<camera2_stream_ops *>(this);
1196}
1197
1198ANativeWindow* Camera2Device::StreamAdapter::toANW(
1199 const camera2_stream_ops_t *w) {
1200 return static_cast<const StreamAdapter*>(w)->mConsumerInterface.get();
1201}
1202
1203int Camera2Device::StreamAdapter::dequeue_buffer(const camera2_stream_ops_t *w,
1204 buffer_handle_t** buffer) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -07001205 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001206 int res;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001207 StreamAdapter* stream =
1208 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
1209 if (stream->mState != ACTIVE) {
1210 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001211 return INVALID_OPERATION;
1212 }
1213
1214 ANativeWindow *a = toANW(w);
1215 ANativeWindowBuffer* anb;
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001216 res = native_window_dequeue_buffer_and_wait(a, &anb);
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001217 if (res != OK) {
1218 ALOGE("Stream %d dequeue: Error from native_window: %s (%d)", stream->mId,
1219 strerror(-res), res);
1220 return res;
1221 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001222
1223 *buffer = &(anb->handle);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001224 stream->mActiveBuffers++;
1225
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001226 ALOGVV("Stream %d dequeue: Buffer %p dequeued", stream->mId, (void*)(**buffer));
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001227 return res;
1228}
1229
1230int Camera2Device::StreamAdapter::enqueue_buffer(const camera2_stream_ops_t* w,
1231 int64_t timestamp,
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 Talvala228a5382012-08-13 12:16:06 -07001236 stream->mFrameCount++;
1237 ALOGVV("Stream %d enqueue: Frame %d (%p) captured at %lld ns",
James Dong6638f3b2012-09-05 16:46:36 -07001238 stream->mId, stream->mFrameCount, (void*)(*buffer), timestamp);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001239 int state = stream->mState;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001240 if (state != ACTIVE) {
1241 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1242 return INVALID_OPERATION;
1243 }
1244 ANativeWindow *a = toANW(w);
1245 status_t err;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001246
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001247 err = native_window_set_buffers_timestamp(a, timestamp);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001248 if (err != OK) {
1249 ALOGE("%s: Error setting timestamp on native window: %s (%d)",
1250 __FUNCTION__, strerror(-err), err);
1251 return err;
1252 }
1253 err = a->queueBuffer(a,
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001254 container_of(buffer, ANativeWindowBuffer, handle), -1);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001255 if (err != OK) {
1256 ALOGE("%s: Error queueing buffer to native window: %s (%d)",
1257 __FUNCTION__, strerror(-err), err);
James Dong31d377b2012-08-09 17:43:46 -07001258 return err;
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001259 }
James Dong31d377b2012-08-09 17:43:46 -07001260
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001261 stream->mActiveBuffers--;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001262 stream->mLastTimestamp = timestamp;
James Dong31d377b2012-08-09 17:43:46 -07001263 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001264}
1265
1266int Camera2Device::StreamAdapter::cancel_buffer(const camera2_stream_ops_t* w,
1267 buffer_handle_t* buffer) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -07001268 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001269 StreamAdapter *stream =
1270 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001271 ALOGVV("Stream %d cancel: Buffer %p",
1272 stream->mId, (void*)(*buffer));
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001273 if (stream->mState != ACTIVE) {
1274 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001275 return INVALID_OPERATION;
1276 }
James Dong31d377b2012-08-09 17:43:46 -07001277
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001278 ANativeWindow *a = toANW(w);
James Dong31d377b2012-08-09 17:43:46 -07001279 int err = a->cancelBuffer(a,
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001280 container_of(buffer, ANativeWindowBuffer, handle), -1);
James Dong31d377b2012-08-09 17:43:46 -07001281 if (err != OK) {
1282 ALOGE("%s: Error canceling buffer to native window: %s (%d)",
1283 __FUNCTION__, strerror(-err), err);
1284 return err;
1285 }
1286
1287 stream->mActiveBuffers--;
1288 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001289}
1290
1291int Camera2Device::StreamAdapter::set_crop(const camera2_stream_ops_t* w,
1292 int left, int top, int right, int bottom) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -07001293 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001294 int state = static_cast<const StreamAdapter*>(w)->mState;
1295 if (state != ACTIVE) {
1296 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1297 return INVALID_OPERATION;
1298 }
1299 ANativeWindow *a = toANW(w);
1300 android_native_rect_t crop = { left, top, right, bottom };
1301 return native_window_set_crop(a, &crop);
1302}
1303
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -07001304/**
1305 * Camera2Device::ReprocessStreamAdapter
1306 */
1307
1308#ifndef container_of
1309#define container_of(ptr, type, member) \
1310 (type *)((char*)(ptr) - offsetof(type, member))
1311#endif
1312
1313Camera2Device::ReprocessStreamAdapter::ReprocessStreamAdapter(camera2_device_t *d):
1314 mState(RELEASED),
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -08001315 mHal2Device(d),
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -07001316 mId(-1),
1317 mWidth(0), mHeight(0), mFormat(0),
1318 mActiveBuffers(0),
1319 mFrameCount(0)
1320{
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -07001321 ATRACE_CALL();
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -07001322 camera2_stream_in_ops::acquire_buffer = acquire_buffer;
1323 camera2_stream_in_ops::release_buffer = release_buffer;
1324}
1325
1326Camera2Device::ReprocessStreamAdapter::~ReprocessStreamAdapter() {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -07001327 ATRACE_CALL();
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -07001328 if (mState != RELEASED) {
1329 release();
1330 }
1331}
1332
1333status_t Camera2Device::ReprocessStreamAdapter::connectToDevice(
1334 const sp<StreamAdapter> &outputStream) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -07001335 ATRACE_CALL();
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -07001336 status_t res;
1337 ALOGV("%s: E", __FUNCTION__);
1338
1339 if (mState != RELEASED) return INVALID_OPERATION;
1340 if (outputStream == NULL) {
1341 ALOGE("%s: Null base stream passed to reprocess stream adapter",
1342 __FUNCTION__);
1343 return BAD_VALUE;
1344 }
1345
1346 mBaseStream = outputStream;
1347 mWidth = outputStream->getWidth();
1348 mHeight = outputStream->getHeight();
1349 mFormat = outputStream->getFormat();
1350
1351 ALOGV("%s: New reprocess stream parameters %d x %d, format 0x%x",
1352 __FUNCTION__, mWidth, mHeight, mFormat);
1353
1354 // Allocate device-side stream interface
1355
1356 uint32_t id;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -08001357 res = mHal2Device->ops->allocate_reprocess_stream_from_stream(mHal2Device,
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -07001358 outputStream->getId(), getStreamOps(),
1359 &id);
1360 if (res != OK) {
1361 ALOGE("%s: Device reprocess stream allocation failed: %s (%d)",
1362 __FUNCTION__, strerror(-res), res);
1363 return res;
1364 }
1365
1366 ALOGV("%s: Allocated reprocess stream id %d based on stream %d",
1367 __FUNCTION__, id, outputStream->getId());
1368
1369 mId = id;
1370
1371 mState = ACTIVE;
1372
1373 return OK;
1374}
1375
1376status_t Camera2Device::ReprocessStreamAdapter::release() {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -07001377 ATRACE_CALL();
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -07001378 status_t res;
1379 ALOGV("%s: Releasing stream %d", __FUNCTION__, mId);
1380 if (mState >= ACTIVE) {
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -08001381 res = mHal2Device->ops->release_reprocess_stream(mHal2Device, mId);
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -07001382 if (res != OK) {
1383 ALOGE("%s: Unable to release stream %d",
1384 __FUNCTION__, mId);
1385 return res;
1386 }
1387 }
1388
1389 List<QueueEntry>::iterator s;
1390 for (s = mQueue.begin(); s != mQueue.end(); s++) {
1391 sp<BufferReleasedListener> listener = s->releaseListener.promote();
1392 if (listener != 0) listener->onBufferReleased(s->handle);
1393 }
1394 for (s = mInFlightQueue.begin(); s != mInFlightQueue.end(); s++) {
1395 sp<BufferReleasedListener> listener = s->releaseListener.promote();
1396 if (listener != 0) listener->onBufferReleased(s->handle);
1397 }
1398 mQueue.clear();
1399 mInFlightQueue.clear();
1400
1401 mState = RELEASED;
1402 return OK;
1403}
1404
1405status_t Camera2Device::ReprocessStreamAdapter::pushIntoStream(
1406 buffer_handle_t *handle, const wp<BufferReleasedListener> &releaseListener) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -07001407 ATRACE_CALL();
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -07001408 // TODO: Some error checking here would be nice
1409 ALOGV("%s: Pushing buffer %p to stream", __FUNCTION__, (void*)(*handle));
1410
1411 QueueEntry entry;
1412 entry.handle = handle;
1413 entry.releaseListener = releaseListener;
1414 mQueue.push_back(entry);
1415 return OK;
1416}
1417
1418status_t Camera2Device::ReprocessStreamAdapter::dump(int fd,
Igor Murashkinddf3c502012-10-12 16:56:11 -07001419 const Vector<String16>& /*args*/) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -07001420 ATRACE_CALL();
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -07001421 String8 result =
1422 String8::format(" Reprocess stream %d: %d x %d, fmt 0x%x\n",
1423 mId, mWidth, mHeight, mFormat);
1424 result.appendFormat(" acquired buffers: %d\n",
1425 mActiveBuffers);
1426 result.appendFormat(" frame count: %d\n",
1427 mFrameCount);
1428 write(fd, result.string(), result.size());
1429 return OK;
1430}
1431
1432const camera2_stream_in_ops *Camera2Device::ReprocessStreamAdapter::getStreamOps() {
1433 return static_cast<camera2_stream_in_ops *>(this);
1434}
1435
1436int Camera2Device::ReprocessStreamAdapter::acquire_buffer(
1437 const camera2_stream_in_ops_t *w,
1438 buffer_handle_t** buffer) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -07001439 ATRACE_CALL();
Igor Murashkinddf3c502012-10-12 16:56:11 -07001440
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -07001441 ReprocessStreamAdapter* stream =
1442 const_cast<ReprocessStreamAdapter*>(
1443 static_cast<const ReprocessStreamAdapter*>(w));
1444 if (stream->mState != ACTIVE) {
1445 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
1446 return INVALID_OPERATION;
1447 }
1448
1449 if (stream->mQueue.empty()) {
1450 *buffer = NULL;
1451 return OK;
1452 }
1453
1454 QueueEntry &entry = *(stream->mQueue.begin());
1455
1456 *buffer = entry.handle;
1457
1458 stream->mInFlightQueue.push_back(entry);
1459 stream->mQueue.erase(stream->mQueue.begin());
1460
1461 stream->mActiveBuffers++;
1462
1463 ALOGV("Stream %d acquire: Buffer %p acquired", stream->mId,
1464 (void*)(**buffer));
1465 return OK;
1466}
1467
1468int Camera2Device::ReprocessStreamAdapter::release_buffer(
1469 const camera2_stream_in_ops_t* w,
1470 buffer_handle_t* buffer) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -07001471 ATRACE_CALL();
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -07001472 ReprocessStreamAdapter *stream =
1473 const_cast<ReprocessStreamAdapter*>(
1474 static_cast<const ReprocessStreamAdapter*>(w) );
1475 stream->mFrameCount++;
1476 ALOGV("Reprocess stream %d release: Frame %d (%p)",
1477 stream->mId, stream->mFrameCount, (void*)*buffer);
1478 int state = stream->mState;
1479 if (state != ACTIVE) {
1480 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1481 return INVALID_OPERATION;
1482 }
1483 stream->mActiveBuffers--;
1484
1485 List<QueueEntry>::iterator s;
1486 for (s = stream->mInFlightQueue.begin(); s != stream->mInFlightQueue.end(); s++) {
1487 if ( s->handle == buffer ) break;
1488 }
1489 if (s == stream->mInFlightQueue.end()) {
1490 ALOGE("%s: Can't find buffer %p in in-flight list!", __FUNCTION__,
1491 buffer);
1492 return INVALID_OPERATION;
1493 }
1494
1495 sp<BufferReleasedListener> listener = s->releaseListener.promote();
1496 if (listener != 0) {
1497 listener->onBufferReleased(s->handle);
1498 } else {
1499 ALOGE("%s: Can't free buffer - missing listener", __FUNCTION__);
1500 }
1501 stream->mInFlightQueue.erase(s);
1502
1503 return OK;
1504}
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001505
1506}; // namespace android