blob: fe2cd771cb4344ef666916e3f191da67a7344e02 [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 Talvala852c3812012-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 Talvala852c3812012-09-24 09:46:53 -070029#include <utils/Trace.h>
Eino-Ville Talvala4c9eb712012-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 Talvala7fa43f32013-02-06 17:20:07 -080037 mHal2Device(NULL)
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070038{
Eino-Ville Talvala852c3812012-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 Talvala852c3812012-09-24 09:46:53 -070045 ATRACE_CALL();
Igor Murashkin8dcdb952012-10-02 16:05:11 -070046 ALOGV("%s: Tearing down for camera id %d", __FUNCTION__, mId);
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -070047 disconnect();
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070048}
49
Igor Murashkin71381052013-03-04 14:53:08 -080050int Camera2Device::getId() const {
51 return mId;
52}
53
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070054status_t Camera2Device::initialize(camera_module_t *module)
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070055{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -070056 ATRACE_CALL();
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -070057 ALOGV("%s: Initializing device for camera %d", __FUNCTION__, mId);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -080058 if (mHal2Device != NULL) {
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -070059 ALOGE("%s: Already initialized!", __FUNCTION__);
60 return INVALID_OPERATION;
61 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -070062
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070063 status_t res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070064 char name[10];
65 snprintf(name, sizeof(name), "%d", mId);
66
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -070067 camera2_device_t *device;
68
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070069 res = module->common.methods->open(&module->common, name,
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -070070 reinterpret_cast<hw_device_t**>(&device));
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070071
72 if (res != OK) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070073 ALOGE("%s: Could not open camera %d: %s (%d)", __FUNCTION__,
74 mId, strerror(-res), res);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070075 return res;
76 }
77
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -070078 if (device->common.version != CAMERA_DEVICE_API_VERSION_2_0) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070079 ALOGE("%s: Could not open camera %d: "
80 "Camera device is not version %x, reports %x instead",
81 __FUNCTION__, mId, CAMERA_DEVICE_API_VERSION_2_0,
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -070082 device->common.version);
83 device->common.close(&device->common);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070084 return BAD_VALUE;
85 }
86
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070087 camera_info info;
88 res = module->get_camera_info(mId, &info);
89 if (res != OK ) return res;
90
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -070091 if (info.device_version != device->common.version) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070092 ALOGE("%s: HAL reporting mismatched camera_info version (%x)"
93 " and device version (%x).", __FUNCTION__,
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -070094 device->common.version, info.device_version);
95 device->common.close(&device->common);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070096 return BAD_VALUE;
97 }
98
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -070099 res = mRequestQueue.setConsumerDevice(device);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700100 if (res != OK) {
101 ALOGE("%s: Camera %d: Unable to connect request queue to device: %s (%d)",
102 __FUNCTION__, mId, strerror(-res), res);
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700103 device->common.close(&device->common);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700104 return res;
105 }
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700106 res = mFrameQueue.setProducerDevice(device);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700107 if (res != OK) {
108 ALOGE("%s: Camera %d: Unable to connect frame queue to device: %s (%d)",
109 __FUNCTION__, mId, strerror(-res), res);
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700110 device->common.close(&device->common);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700111 return res;
112 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700113
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700114 res = device->ops->get_metadata_vendor_tag_ops(device, &mVendorTagOps);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700115 if (res != OK ) {
116 ALOGE("%s: Camera %d: Unable to retrieve tag ops from device: %s (%d)",
117 __FUNCTION__, mId, strerror(-res), res);
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700118 device->common.close(&device->common);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700119 return res;
120 }
Shuzhen Wang314079e2012-08-31 10:24:22 -0700121 res = set_camera_metadata_vendor_tag_ops(mVendorTagOps);
122 if (res != OK) {
123 ALOGE("%s: Camera %d: Unable to set tag ops: %s (%d)",
124 __FUNCTION__, mId, strerror(-res), res);
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700125 device->common.close(&device->common);
Shuzhen Wang314079e2012-08-31 10:24:22 -0700126 return res;
127 }
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700128 res = device->ops->set_notify_callback(device, notificationCallback,
129 NULL);
130 if (res != OK) {
131 ALOGE("%s: Camera %d: Unable to initialize notification callback!",
132 __FUNCTION__, mId);
133 device->common.close(&device->common);
134 return res;
135 }
136
137 mDeviceInfo = info.static_camera_characteristics;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800138 mHal2Device = device;
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700139
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700140 return OK;
141}
142
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700143status_t Camera2Device::disconnect() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700144 ATRACE_CALL();
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700145 status_t res = OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800146 if (mHal2Device) {
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700147 ALOGV("%s: Closing device for camera %d", __FUNCTION__, mId);
148
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800149 int inProgressCount = mHal2Device->ops->get_in_progress_count(mHal2Device);
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700150 if (inProgressCount > 0) {
151 ALOGW("%s: Closing camera device %d with %d requests in flight!",
152 __FUNCTION__, mId, inProgressCount);
153 }
Eino-Ville Talvalac62bb782012-09-24 13:44:07 -0700154 mReprocessStreams.clear();
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700155 mStreams.clear();
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800156 res = mHal2Device->common.close(&mHal2Device->common);
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700157 if (res != OK) {
158 ALOGE("%s: Could not close camera %d: %s (%d)",
159 __FUNCTION__,
160 mId, strerror(-res), res);
161 }
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800162 mHal2Device = NULL;
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700163 ALOGV("%s: Shutdown complete", __FUNCTION__);
164 }
165 return res;
166}
167
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700168status_t Camera2Device::dump(int fd, const Vector<String16>& args) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700169 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700170 String8 result;
Eino-Ville Talvala97197152012-08-06 14:25:19 -0700171 int detailLevel = 0;
172 int n = args.size();
173 String16 detailOption("-d");
174 for (int i = 0; i + 1 < n; i++) {
175 if (args[i] == detailOption) {
176 String8 levelStr(args[i+1]);
177 detailLevel = atoi(levelStr.string());
178 }
179 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700180
Eino-Ville Talvala603b12e2012-08-08 09:25:58 -0700181 result.appendFormat(" Camera2Device[%d] dump (detail level %d):\n",
182 mId, detailLevel);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700183
Eino-Ville Talvala97197152012-08-06 14:25:19 -0700184 if (detailLevel > 0) {
185 result = " Request queue contents:\n";
186 write(fd, result.string(), result.size());
187 mRequestQueue.dump(fd, args);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700188
Eino-Ville Talvala97197152012-08-06 14:25:19 -0700189 result = " Frame queue contents:\n";
190 write(fd, result.string(), result.size());
191 mFrameQueue.dump(fd, args);
192 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700193
194 result = " Active streams:\n";
195 write(fd, result.string(), result.size());
196 for (StreamList::iterator s = mStreams.begin(); s != mStreams.end(); s++) {
197 (*s)->dump(fd, args);
198 }
199
200 result = " HAL device dump:\n";
201 write(fd, result.string(), result.size());
202
203 status_t res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800204 res = mHal2Device->ops->dump(mHal2Device, fd);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700205
206 return res;
207}
208
Igor Murashkinbd02dd12013-02-13 15:53:56 -0800209const CameraMetadata& Camera2Device::info() const {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700210 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700211
212 return mDeviceInfo;
213}
214
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700215status_t Camera2Device::capture(CameraMetadata &request) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700216 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700217 ALOGV("%s: E", __FUNCTION__);
218
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700219 mRequestQueue.enqueue(request.release());
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700220 return OK;
221}
222
223
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700224status_t Camera2Device::setStreamingRequest(const CameraMetadata &request) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700225 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700226 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700227 CameraMetadata streamRequest(request);
228 return mRequestQueue.setStreamSlot(streamRequest.release());
229}
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700230
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700231status_t Camera2Device::clearStreamingRequest() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700232 ATRACE_CALL();
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700233 return mRequestQueue.setStreamSlot(NULL);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700234}
235
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700236status_t Camera2Device::waitUntilRequestReceived(int32_t requestId, nsecs_t timeout) {
237 ATRACE_CALL();
238 return mRequestQueue.waitForDequeue(requestId, timeout);
239}
240
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700241status_t Camera2Device::createStream(sp<ANativeWindow> consumer,
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700242 uint32_t width, uint32_t height, int format, size_t size, int *id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700243 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700244 status_t res;
245 ALOGV("%s: E", __FUNCTION__);
246
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800247 sp<StreamAdapter> stream = new StreamAdapter(mHal2Device);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700248
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700249 res = stream->connectToDevice(consumer, width, height, format, size);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700250 if (res != OK) {
251 ALOGE("%s: Camera %d: Unable to create stream (%d x %d, format %x):"
252 "%s (%d)",
253 __FUNCTION__, mId, width, height, format, strerror(-res), res);
254 return res;
255 }
256
257 *id = stream->getId();
258
259 mStreams.push_back(stream);
260 return OK;
261}
262
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700263status_t Camera2Device::createReprocessStreamFromStream(int outputId, int *id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700264 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700265 status_t res;
266 ALOGV("%s: E", __FUNCTION__);
267
268 bool found = false;
269 StreamList::iterator streamI;
270 for (streamI = mStreams.begin();
271 streamI != mStreams.end(); streamI++) {
272 if ((*streamI)->getId() == outputId) {
273 found = true;
274 break;
275 }
276 }
277 if (!found) {
278 ALOGE("%s: Camera %d: Output stream %d doesn't exist; can't create "
279 "reprocess stream from it!", __FUNCTION__, mId, outputId);
280 return BAD_VALUE;
281 }
282
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800283 sp<ReprocessStreamAdapter> stream = new ReprocessStreamAdapter(mHal2Device);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700284
285 res = stream->connectToDevice((*streamI));
286 if (res != OK) {
287 ALOGE("%s: Camera %d: Unable to create reprocessing stream from "\
288 "stream %d: %s (%d)", __FUNCTION__, mId, outputId,
289 strerror(-res), res);
290 return res;
291 }
292
293 *id = stream->getId();
294
295 mReprocessStreams.push_back(stream);
296 return OK;
297}
298
299
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700300status_t Camera2Device::getStreamInfo(int id,
301 uint32_t *width, uint32_t *height, uint32_t *format) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700302 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700303 ALOGV("%s: E", __FUNCTION__);
304 bool found = false;
305 StreamList::iterator streamI;
306 for (streamI = mStreams.begin();
307 streamI != mStreams.end(); streamI++) {
308 if ((*streamI)->getId() == id) {
309 found = true;
310 break;
311 }
312 }
313 if (!found) {
314 ALOGE("%s: Camera %d: Stream %d does not exist",
315 __FUNCTION__, mId, id);
316 return BAD_VALUE;
317 }
318
319 if (width) *width = (*streamI)->getWidth();
320 if (height) *height = (*streamI)->getHeight();
321 if (format) *format = (*streamI)->getFormat();
322
323 return OK;
324}
325
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -0700326status_t Camera2Device::setStreamTransform(int id,
327 int transform) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700328 ATRACE_CALL();
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -0700329 ALOGV("%s: E", __FUNCTION__);
330 bool found = false;
331 StreamList::iterator streamI;
332 for (streamI = mStreams.begin();
333 streamI != mStreams.end(); streamI++) {
334 if ((*streamI)->getId() == id) {
335 found = true;
336 break;
337 }
338 }
339 if (!found) {
340 ALOGE("%s: Camera %d: Stream %d does not exist",
341 __FUNCTION__, mId, id);
342 return BAD_VALUE;
343 }
344
345 return (*streamI)->setTransform(transform);
346}
347
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700348status_t Camera2Device::deleteStream(int id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700349 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700350 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700351 bool found = false;
352 for (StreamList::iterator streamI = mStreams.begin();
353 streamI != mStreams.end(); streamI++) {
354 if ((*streamI)->getId() == id) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700355 status_t res = (*streamI)->release();
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700356 if (res != OK) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700357 ALOGE("%s: Unable to release stream %d from HAL device: "
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700358 "%s (%d)", __FUNCTION__, id, strerror(-res), res);
359 return res;
360 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700361 mStreams.erase(streamI);
362 found = true;
363 break;
364 }
365 }
366 if (!found) {
367 ALOGE("%s: Camera %d: Unable to find stream %d to delete",
368 __FUNCTION__, mId, id);
369 return BAD_VALUE;
370 }
371 return OK;
372}
373
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700374status_t Camera2Device::deleteReprocessStream(int id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700375 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700376 ALOGV("%s: E", __FUNCTION__);
377 bool found = false;
378 for (ReprocessStreamList::iterator streamI = mReprocessStreams.begin();
379 streamI != mReprocessStreams.end(); streamI++) {
380 if ((*streamI)->getId() == id) {
381 status_t res = (*streamI)->release();
382 if (res != OK) {
383 ALOGE("%s: Unable to release reprocess stream %d from "
384 "HAL device: %s (%d)", __FUNCTION__, id,
385 strerror(-res), res);
386 return res;
387 }
388 mReprocessStreams.erase(streamI);
389 found = true;
390 break;
391 }
392 }
393 if (!found) {
394 ALOGE("%s: Camera %d: Unable to find stream %d to delete",
395 __FUNCTION__, mId, id);
396 return BAD_VALUE;
397 }
398 return OK;
399}
400
401
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700402status_t Camera2Device::createDefaultRequest(int templateId,
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700403 CameraMetadata *request) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700404 ATRACE_CALL();
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700405 status_t err;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700406 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700407 camera_metadata_t *rawRequest;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800408 err = mHal2Device->ops->construct_default_request(
409 mHal2Device, templateId, &rawRequest);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700410 request->acquire(rawRequest);
411 return err;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700412}
413
414status_t Camera2Device::waitUntilDrained() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700415 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700416 static const uint32_t kSleepTime = 50000; // 50 ms
417 static const uint32_t kMaxSleepTime = 10000000; // 10 s
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700418 ALOGV("%s: Camera %d: Starting wait", __FUNCTION__, mId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700419 if (mRequestQueue.getBufferCount() ==
420 CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS) return INVALID_OPERATION;
421
422 // TODO: Set up notifications from HAL, instead of sleeping here
423 uint32_t totalTime = 0;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800424 while (mHal2Device->ops->get_in_progress_count(mHal2Device) > 0) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700425 usleep(kSleepTime);
426 totalTime += kSleepTime;
427 if (totalTime > kMaxSleepTime) {
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700428 ALOGE("%s: Waited %d us, %d requests still in flight", __FUNCTION__,
Alex Rayf0eeb532013-03-17 03:23:18 -0700429 totalTime, mHal2Device->ops->get_in_progress_count(mHal2Device));
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700430 return TIMED_OUT;
431 }
432 }
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700433 ALOGV("%s: Camera %d: HAL is idle", __FUNCTION__, mId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700434 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700435}
436
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700437status_t Camera2Device::setNotifyCallback(NotificationListener *listener) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700438 ATRACE_CALL();
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700439 status_t res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800440 res = mHal2Device->ops->set_notify_callback(mHal2Device, notificationCallback,
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700441 reinterpret_cast<void*>(listener) );
442 if (res != OK) {
443 ALOGE("%s: Unable to set notification callback!", __FUNCTION__);
444 }
445 return res;
446}
447
Eino-Ville Talvala46910bd2013-07-18 19:15:17 -0700448bool Camera2Device::willNotify3A() {
449 return true;
450}
451
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700452void Camera2Device::notificationCallback(int32_t msg_type,
453 int32_t ext1,
454 int32_t ext2,
455 int32_t ext3,
456 void *user) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700457 ATRACE_CALL();
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700458 NotificationListener *listener = reinterpret_cast<NotificationListener*>(user);
459 ALOGV("%s: Notification %d, arguments %d, %d, %d", __FUNCTION__, msg_type,
460 ext1, ext2, ext3);
461 if (listener != NULL) {
462 switch (msg_type) {
463 case CAMERA2_MSG_ERROR:
464 listener->notifyError(ext1, ext2, ext3);
465 break;
466 case CAMERA2_MSG_SHUTTER: {
467 nsecs_t timestamp = (nsecs_t)ext2 | ((nsecs_t)(ext3) << 32 );
468 listener->notifyShutter(ext1, timestamp);
469 break;
470 }
471 case CAMERA2_MSG_AUTOFOCUS:
472 listener->notifyAutoFocus(ext1, ext2);
473 break;
474 case CAMERA2_MSG_AUTOEXPOSURE:
475 listener->notifyAutoExposure(ext1, ext2);
476 break;
477 case CAMERA2_MSG_AUTOWB:
478 listener->notifyAutoWhitebalance(ext1, ext2);
479 break;
480 default:
481 ALOGE("%s: Unknown notification %d (arguments %d, %d, %d)!",
482 __FUNCTION__, msg_type, ext1, ext2, ext3);
483 }
484 }
485}
486
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -0700487status_t Camera2Device::waitForNextFrame(nsecs_t timeout) {
488 return mFrameQueue.waitForBuffer(timeout);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700489}
490
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700491status_t Camera2Device::getNextFrame(CameraMetadata *frame) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700492 ATRACE_CALL();
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700493 status_t res;
494 camera_metadata_t *rawFrame;
495 res = mFrameQueue.dequeue(&rawFrame);
496 if (rawFrame == NULL) {
497 return NOT_ENOUGH_DATA;
498 } else if (res == OK) {
499 frame->acquire(rawFrame);
500 }
501 return res;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700502}
503
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700504status_t Camera2Device::triggerAutofocus(uint32_t id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700505 ATRACE_CALL();
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700506 status_t res;
507 ALOGV("%s: Triggering autofocus, id %d", __FUNCTION__, id);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800508 res = mHal2Device->ops->trigger_action(mHal2Device,
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700509 CAMERA2_TRIGGER_AUTOFOCUS, id, 0);
510 if (res != OK) {
511 ALOGE("%s: Error triggering autofocus (id %d)",
512 __FUNCTION__, id);
513 }
514 return res;
515}
516
517status_t Camera2Device::triggerCancelAutofocus(uint32_t id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700518 ATRACE_CALL();
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700519 status_t res;
520 ALOGV("%s: Canceling autofocus, id %d", __FUNCTION__, id);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800521 res = mHal2Device->ops->trigger_action(mHal2Device,
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700522 CAMERA2_TRIGGER_CANCEL_AUTOFOCUS, id, 0);
523 if (res != OK) {
524 ALOGE("%s: Error canceling autofocus (id %d)",
525 __FUNCTION__, id);
526 }
527 return res;
528}
529
530status_t Camera2Device::triggerPrecaptureMetering(uint32_t id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700531 ATRACE_CALL();
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700532 status_t res;
533 ALOGV("%s: Triggering precapture metering, id %d", __FUNCTION__, id);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800534 res = mHal2Device->ops->trigger_action(mHal2Device,
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700535 CAMERA2_TRIGGER_PRECAPTURE_METERING, id, 0);
536 if (res != OK) {
537 ALOGE("%s: Error triggering precapture metering (id %d)",
538 __FUNCTION__, id);
539 }
540 return res;
541}
542
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700543status_t Camera2Device::pushReprocessBuffer(int reprocessStreamId,
544 buffer_handle_t *buffer, wp<BufferReleasedListener> listener) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700545 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700546 ALOGV("%s: E", __FUNCTION__);
547 bool found = false;
548 status_t res = OK;
549 for (ReprocessStreamList::iterator streamI = mReprocessStreams.begin();
550 streamI != mReprocessStreams.end(); streamI++) {
551 if ((*streamI)->getId() == reprocessStreamId) {
552 res = (*streamI)->pushIntoStream(buffer, listener);
553 if (res != OK) {
554 ALOGE("%s: Unable to push buffer to reprocess stream %d: %s (%d)",
555 __FUNCTION__, reprocessStreamId, strerror(-res), res);
556 return res;
557 }
558 found = true;
559 break;
560 }
561 }
562 if (!found) {
563 ALOGE("%s: Camera %d: Unable to find reprocess stream %d",
564 __FUNCTION__, mId, reprocessStreamId);
565 res = BAD_VALUE;
566 }
567 return res;
568}
569
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -0700570status_t Camera2Device::flush() {
571 ATRACE_CALL();
572
573 mRequestQueue.clear();
574 return waitUntilDrained();
575}
576
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700577/**
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700578 * Camera2Device::MetadataQueue
579 */
580
581Camera2Device::MetadataQueue::MetadataQueue():
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800582 mHal2Device(NULL),
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700583 mFrameCount(0),
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700584 mLatestRequestId(0),
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700585 mCount(0),
586 mStreamSlotCount(0),
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -0700587 mSignalConsumer(true)
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700588{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700589 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700590 camera2_request_queue_src_ops::dequeue_request = consumer_dequeue;
591 camera2_request_queue_src_ops::request_count = consumer_buffer_count;
592 camera2_request_queue_src_ops::free_request = consumer_free;
593
594 camera2_frame_queue_dst_ops::dequeue_frame = producer_dequeue;
595 camera2_frame_queue_dst_ops::cancel_frame = producer_cancel;
596 camera2_frame_queue_dst_ops::enqueue_frame = producer_enqueue;
597}
598
599Camera2Device::MetadataQueue::~MetadataQueue() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700600 ATRACE_CALL();
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -0700601 clear();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700602}
603
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700604// Connect to camera2 HAL as consumer (input requests/reprocessing)
605status_t Camera2Device::MetadataQueue::setConsumerDevice(camera2_device_t *d) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700606 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700607 status_t res;
608 res = d->ops->set_request_queue_src_ops(d,
609 this);
610 if (res != OK) return res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800611 mHal2Device = d;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700612 return OK;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700613}
614
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700615status_t Camera2Device::MetadataQueue::setProducerDevice(camera2_device_t *d) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700616 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700617 status_t res;
618 res = d->ops->set_frame_queue_dst_ops(d,
619 this);
620 return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700621}
622
623// Real interfaces
624status_t Camera2Device::MetadataQueue::enqueue(camera_metadata_t *buf) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700625 ATRACE_CALL();
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700626 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700627 Mutex::Autolock l(mMutex);
628
629 mCount++;
630 mEntries.push_back(buf);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700631
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700632 return signalConsumerLocked();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700633}
634
635int Camera2Device::MetadataQueue::getBufferCount() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700636 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700637 Mutex::Autolock l(mMutex);
638 if (mStreamSlotCount > 0) {
639 return CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS;
640 }
641 return mCount;
642}
643
644status_t Camera2Device::MetadataQueue::dequeue(camera_metadata_t **buf,
645 bool incrementCount)
646{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700647 ATRACE_CALL();
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700648 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700649 status_t res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700650 Mutex::Autolock l(mMutex);
651
652 if (mCount == 0) {
653 if (mStreamSlotCount == 0) {
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700654 ALOGVV("%s: Empty", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700655 *buf = NULL;
656 mSignalConsumer = true;
657 return OK;
658 }
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700659 ALOGVV("%s: Streaming %d frames to queue", __FUNCTION__,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700660 mStreamSlotCount);
661
662 for (List<camera_metadata_t*>::iterator slotEntry = mStreamSlot.begin();
663 slotEntry != mStreamSlot.end();
664 slotEntry++ ) {
665 size_t entries = get_camera_metadata_entry_count(*slotEntry);
666 size_t dataBytes = get_camera_metadata_data_count(*slotEntry);
667
668 camera_metadata_t *copy =
669 allocate_camera_metadata(entries, dataBytes);
670 append_camera_metadata(copy, *slotEntry);
671 mEntries.push_back(copy);
672 }
673 mCount = mStreamSlotCount;
674 }
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700675 ALOGVV("MetadataQueue: deque (%d buffers)", mCount);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700676 camera_metadata_t *b = *(mEntries.begin());
677 mEntries.erase(mEntries.begin());
678
679 if (incrementCount) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700680 ATRACE_INT("cam2_request", mFrameCount);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700681 camera_metadata_entry_t frameCount;
682 res = find_camera_metadata_entry(b,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700683 ANDROID_REQUEST_FRAME_COUNT,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700684 &frameCount);
685 if (res != OK) {
686 ALOGE("%s: Unable to add frame count: %s (%d)",
687 __FUNCTION__, strerror(-res), res);
688 } else {
689 *frameCount.data.i32 = mFrameCount;
690 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700691 mFrameCount++;
692 }
693
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700694 // Check for request ID, and if present, signal waiters.
695 camera_metadata_entry_t requestId;
696 res = find_camera_metadata_entry(b,
697 ANDROID_REQUEST_ID,
698 &requestId);
699 if (res == OK) {
700 mLatestRequestId = requestId.data.i32[0];
701 mNewRequestId.signal();
702 }
703
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700704 *buf = b;
705 mCount--;
706
707 return OK;
708}
709
710status_t Camera2Device::MetadataQueue::waitForBuffer(nsecs_t timeout)
711{
712 Mutex::Autolock l(mMutex);
713 status_t res;
714 while (mCount == 0) {
715 res = notEmpty.waitRelative(mMutex,timeout);
716 if (res != OK) return res;
717 }
718 return OK;
719}
720
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700721status_t Camera2Device::MetadataQueue::waitForDequeue(int32_t id,
722 nsecs_t timeout) {
723 Mutex::Autolock l(mMutex);
724 status_t res;
725 while (mLatestRequestId != id) {
726 nsecs_t startTime = systemTime();
727
728 res = mNewRequestId.waitRelative(mMutex, timeout);
729 if (res != OK) return res;
730
731 timeout -= (systemTime() - startTime);
732 }
733
734 return OK;
735}
736
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700737status_t Camera2Device::MetadataQueue::setStreamSlot(camera_metadata_t *buf)
738{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700739 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700740 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700741 Mutex::Autolock l(mMutex);
742 if (buf == NULL) {
743 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
744 mStreamSlotCount = 0;
745 return OK;
746 }
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700747 camera_metadata_t *buf2 = clone_camera_metadata(buf);
748 if (!buf2) {
749 ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__);
750 return NO_MEMORY;
751 }
752
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700753 if (mStreamSlotCount > 1) {
754 List<camera_metadata_t*>::iterator deleter = ++mStreamSlot.begin();
755 freeBuffers(++mStreamSlot.begin(), mStreamSlot.end());
756 mStreamSlotCount = 1;
757 }
758 if (mStreamSlotCount == 1) {
759 free_camera_metadata( *(mStreamSlot.begin()) );
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700760 *(mStreamSlot.begin()) = buf2;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700761 } else {
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700762 mStreamSlot.push_front(buf2);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700763 mStreamSlotCount = 1;
764 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700765 return signalConsumerLocked();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700766}
767
768status_t Camera2Device::MetadataQueue::setStreamSlot(
769 const List<camera_metadata_t*> &bufs)
770{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700771 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700772 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700773 Mutex::Autolock l(mMutex);
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700774
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700775 if (mStreamSlotCount > 0) {
776 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
777 }
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700778 mStreamSlotCount = 0;
779 for (List<camera_metadata_t*>::const_iterator r = bufs.begin();
780 r != bufs.end(); r++) {
781 camera_metadata_t *r2 = clone_camera_metadata(*r);
782 if (!r2) {
783 ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__);
784 return NO_MEMORY;
785 }
786 mStreamSlot.push_back(r2);
787 mStreamSlotCount++;
788 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700789 return signalConsumerLocked();
790}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700791
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -0700792status_t Camera2Device::MetadataQueue::clear()
793{
794 ATRACE_CALL();
795 ALOGV("%s: E", __FUNCTION__);
796
797 Mutex::Autolock l(mMutex);
798
799 // Clear streaming slot
800 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
801 mStreamSlotCount = 0;
802
803 // Clear request queue
804 freeBuffers(mEntries.begin(), mEntries.end());
805 mCount = 0;
806 return OK;
807}
808
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700809status_t Camera2Device::MetadataQueue::dump(int fd,
Igor Murashkinebe3f692012-10-12 16:56:11 -0700810 const Vector<String16>& /*args*/) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700811 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700812 String8 result;
813 status_t notLocked;
814 notLocked = mMutex.tryLock();
815 if (notLocked) {
816 result.append(" (Unable to lock queue mutex)\n");
817 }
818 result.appendFormat(" Current frame number: %d\n", mFrameCount);
819 if (mStreamSlotCount == 0) {
820 result.append(" Stream slot: Empty\n");
821 write(fd, result.string(), result.size());
822 } else {
823 result.appendFormat(" Stream slot: %d entries\n",
824 mStreamSlot.size());
825 int i = 0;
826 for (List<camera_metadata_t*>::iterator r = mStreamSlot.begin();
827 r != mStreamSlot.end(); r++) {
828 result = String8::format(" Stream slot buffer %d:\n", i);
829 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700830 dump_indented_camera_metadata(*r, fd, 2, 10);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700831 i++;
832 }
833 }
834 if (mEntries.size() == 0) {
835 result = " Main queue is empty\n";
836 write(fd, result.string(), result.size());
837 } else {
838 result = String8::format(" Main queue has %d entries:\n",
839 mEntries.size());
840 int i = 0;
841 for (List<camera_metadata_t*>::iterator r = mEntries.begin();
842 r != mEntries.end(); r++) {
843 result = String8::format(" Queue entry %d:\n", i);
844 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700845 dump_indented_camera_metadata(*r, fd, 2, 10);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700846 i++;
847 }
848 }
849
850 if (notLocked == 0) {
851 mMutex.unlock();
852 }
853
854 return OK;
855}
856
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700857status_t Camera2Device::MetadataQueue::signalConsumerLocked() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700858 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700859 status_t res = OK;
860 notEmpty.signal();
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800861 if (mSignalConsumer && mHal2Device != NULL) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700862 mSignalConsumer = false;
863
864 mMutex.unlock();
865 ALOGV("%s: Signaling consumer", __FUNCTION__);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800866 res = mHal2Device->ops->notify_request_queue_not_empty(mHal2Device);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700867 mMutex.lock();
868 }
869 return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700870}
871
872status_t Camera2Device::MetadataQueue::freeBuffers(
873 List<camera_metadata_t*>::iterator start,
874 List<camera_metadata_t*>::iterator end)
875{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700876 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700877 while (start != end) {
878 free_camera_metadata(*start);
879 start = mStreamSlot.erase(start);
880 }
881 return OK;
882}
883
884Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
885 const camera2_request_queue_src_ops_t *q)
886{
887 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
888 return const_cast<MetadataQueue*>(cmq);
889}
890
891Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
892 const camera2_frame_queue_dst_ops_t *q)
893{
894 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
895 return const_cast<MetadataQueue*>(cmq);
896}
897
898int Camera2Device::MetadataQueue::consumer_buffer_count(
899 const camera2_request_queue_src_ops_t *q)
900{
901 MetadataQueue *queue = getInstance(q);
902 return queue->getBufferCount();
903}
904
905int Camera2Device::MetadataQueue::consumer_dequeue(
906 const camera2_request_queue_src_ops_t *q,
907 camera_metadata_t **buffer)
908{
909 MetadataQueue *queue = getInstance(q);
910 return queue->dequeue(buffer, true);
911}
912
913int Camera2Device::MetadataQueue::consumer_free(
914 const camera2_request_queue_src_ops_t *q,
915 camera_metadata_t *old_buffer)
916{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700917 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700918 MetadataQueue *queue = getInstance(q);
Igor Murashkinebe3f692012-10-12 16:56:11 -0700919 (void)queue;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700920 free_camera_metadata(old_buffer);
921 return OK;
922}
923
924int Camera2Device::MetadataQueue::producer_dequeue(
Igor Murashkinebe3f692012-10-12 16:56:11 -0700925 const camera2_frame_queue_dst_ops_t * /*q*/,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700926 size_t entries, size_t bytes,
927 camera_metadata_t **buffer)
928{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700929 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700930 camera_metadata_t *new_buffer =
931 allocate_camera_metadata(entries, bytes);
932 if (new_buffer == NULL) return NO_MEMORY;
933 *buffer = new_buffer;
934 return OK;
935}
936
937int Camera2Device::MetadataQueue::producer_cancel(
Igor Murashkinebe3f692012-10-12 16:56:11 -0700938 const camera2_frame_queue_dst_ops_t * /*q*/,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700939 camera_metadata_t *old_buffer)
940{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700941 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700942 free_camera_metadata(old_buffer);
943 return OK;
944}
945
946int Camera2Device::MetadataQueue::producer_enqueue(
947 const camera2_frame_queue_dst_ops_t *q,
948 camera_metadata_t *filled_buffer)
949{
950 MetadataQueue *queue = getInstance(q);
951 return queue->enqueue(filled_buffer);
952}
953
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700954/**
955 * Camera2Device::StreamAdapter
956 */
957
958#ifndef container_of
959#define container_of(ptr, type, member) \
960 (type *)((char*)(ptr) - offsetof(type, member))
961#endif
962
963Camera2Device::StreamAdapter::StreamAdapter(camera2_device_t *d):
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700964 mState(RELEASED),
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800965 mHal2Device(d),
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700966 mId(-1),
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700967 mWidth(0), mHeight(0), mFormat(0), mSize(0), mUsage(0),
968 mMaxProducerBuffers(0), mMaxConsumerBuffers(0),
969 mTotalBuffers(0),
970 mFormatRequested(0),
971 mActiveBuffers(0),
972 mFrameCount(0),
973 mLastTimestamp(0)
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700974{
975 camera2_stream_ops::dequeue_buffer = dequeue_buffer;
976 camera2_stream_ops::enqueue_buffer = enqueue_buffer;
977 camera2_stream_ops::cancel_buffer = cancel_buffer;
978 camera2_stream_ops::set_crop = set_crop;
979}
980
981Camera2Device::StreamAdapter::~StreamAdapter() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700982 ATRACE_CALL();
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700983 if (mState != RELEASED) {
984 release();
985 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700986}
987
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700988status_t Camera2Device::StreamAdapter::connectToDevice(
989 sp<ANativeWindow> consumer,
990 uint32_t width, uint32_t height, int format, size_t size) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700991 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700992 status_t res;
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700993 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700994
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700995 if (mState != RELEASED) return INVALID_OPERATION;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700996 if (consumer == NULL) {
997 ALOGE("%s: Null consumer passed to stream adapter", __FUNCTION__);
998 return BAD_VALUE;
999 }
1000
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001001 ALOGV("%s: New stream parameters %d x %d, format 0x%x, size %d",
1002 __FUNCTION__, width, height, format, size);
1003
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001004 mConsumerInterface = consumer;
1005 mWidth = width;
1006 mHeight = height;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001007 mSize = (format == HAL_PIXEL_FORMAT_BLOB) ? size : 0;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001008 mFormatRequested = format;
1009
1010 // Allocate device-side stream interface
1011
1012 uint32_t id;
1013 uint32_t formatActual;
1014 uint32_t usage;
1015 uint32_t maxBuffers = 2;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001016 res = mHal2Device->ops->allocate_stream(mHal2Device,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001017 mWidth, mHeight, mFormatRequested, getStreamOps(),
1018 &id, &formatActual, &usage, &maxBuffers);
1019 if (res != OK) {
1020 ALOGE("%s: Device stream allocation failed: %s (%d)",
1021 __FUNCTION__, strerror(-res), res);
1022 return res;
1023 }
1024
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001025 ALOGV("%s: Allocated stream id %d, actual format 0x%x, "
1026 "usage 0x%x, producer wants %d buffers", __FUNCTION__,
1027 id, formatActual, usage, maxBuffers);
1028
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001029 mId = id;
1030 mFormat = formatActual;
1031 mUsage = usage;
1032 mMaxProducerBuffers = maxBuffers;
1033
1034 mState = ALLOCATED;
1035
1036 // Configure consumer-side ANativeWindow interface
1037 res = native_window_api_connect(mConsumerInterface.get(),
1038 NATIVE_WINDOW_API_CAMERA);
1039 if (res != OK) {
1040 ALOGE("%s: Unable to connect to native window for stream %d",
1041 __FUNCTION__, mId);
1042
1043 return res;
1044 }
1045
1046 mState = CONNECTED;
1047
1048 res = native_window_set_usage(mConsumerInterface.get(), mUsage);
1049 if (res != OK) {
1050 ALOGE("%s: Unable to configure usage %08x for stream %d",
1051 __FUNCTION__, mUsage, mId);
1052 return res;
1053 }
1054
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001055 res = native_window_set_scaling_mode(mConsumerInterface.get(),
1056 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
1057 if (res != OK) {
1058 ALOGE("%s: Unable to configure stream scaling: %s (%d)",
1059 __FUNCTION__, strerror(-res), res);
1060 return res;
1061 }
1062
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001063 res = setTransform(0);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001064 if (res != OK) {
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001065 return res;
1066 }
1067
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001068 if (mFormat == HAL_PIXEL_FORMAT_BLOB) {
1069 res = native_window_set_buffers_geometry(mConsumerInterface.get(),
1070 mSize, 1, mFormat);
1071 if (res != OK) {
1072 ALOGE("%s: Unable to configure compressed stream buffer geometry"
1073 " %d x %d, size %d for stream %d",
1074 __FUNCTION__, mWidth, mHeight, mSize, mId);
1075 return res;
1076 }
1077 } else {
1078 res = native_window_set_buffers_geometry(mConsumerInterface.get(),
1079 mWidth, mHeight, mFormat);
1080 if (res != OK) {
1081 ALOGE("%s: Unable to configure stream buffer geometry"
1082 " %d x %d, format 0x%x for stream %d",
1083 __FUNCTION__, mWidth, mHeight, mFormat, mId);
1084 return res;
1085 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001086 }
1087
1088 int maxConsumerBuffers;
1089 res = mConsumerInterface->query(mConsumerInterface.get(),
1090 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &maxConsumerBuffers);
1091 if (res != OK) {
1092 ALOGE("%s: Unable to query consumer undequeued"
1093 " buffer count for stream %d", __FUNCTION__, mId);
1094 return res;
1095 }
1096 mMaxConsumerBuffers = maxConsumerBuffers;
1097
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001098 ALOGV("%s: Consumer wants %d buffers", __FUNCTION__,
1099 mMaxConsumerBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001100
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001101 mTotalBuffers = mMaxConsumerBuffers + mMaxProducerBuffers;
1102 mActiveBuffers = 0;
1103 mFrameCount = 0;
1104 mLastTimestamp = 0;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001105
1106 res = native_window_set_buffer_count(mConsumerInterface.get(),
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001107 mTotalBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001108 if (res != OK) {
1109 ALOGE("%s: Unable to set buffer count for stream %d",
1110 __FUNCTION__, mId);
1111 return res;
1112 }
1113
1114 // Register allocated buffers with HAL device
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001115 buffer_handle_t *buffers = new buffer_handle_t[mTotalBuffers];
1116 ANativeWindowBuffer **anwBuffers = new ANativeWindowBuffer*[mTotalBuffers];
1117 uint32_t bufferIdx = 0;
1118 for (; bufferIdx < mTotalBuffers; bufferIdx++) {
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001119 res = native_window_dequeue_buffer_and_wait(mConsumerInterface.get(),
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001120 &anwBuffers[bufferIdx]);
1121 if (res != OK) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001122 ALOGE("%s: Unable to dequeue buffer %d for initial registration for "
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001123 "stream %d", __FUNCTION__, bufferIdx, mId);
1124 goto cleanUpBuffers;
1125 }
1126
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001127 buffers[bufferIdx] = anwBuffers[bufferIdx]->handle;
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001128 ALOGV("%s: Buffer %p allocated", __FUNCTION__, (void*)buffers[bufferIdx]);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001129 }
1130
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001131 ALOGV("%s: Registering %d buffers with camera HAL", __FUNCTION__, mTotalBuffers);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001132 res = mHal2Device->ops->register_stream_buffers(mHal2Device,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001133 mId,
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001134 mTotalBuffers,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001135 buffers);
1136 if (res != OK) {
1137 ALOGE("%s: Unable to register buffers with HAL device for stream %d",
1138 __FUNCTION__, mId);
1139 } else {
1140 mState = ACTIVE;
1141 }
1142
1143cleanUpBuffers:
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001144 ALOGV("%s: Cleaning up %d buffers", __FUNCTION__, bufferIdx);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001145 for (uint32_t i = 0; i < bufferIdx; i++) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001146 res = mConsumerInterface->cancelBuffer(mConsumerInterface.get(),
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001147 anwBuffers[i], -1);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001148 if (res != OK) {
1149 ALOGE("%s: Unable to cancel buffer %d after registration",
1150 __FUNCTION__, i);
1151 }
1152 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001153 delete[] anwBuffers;
1154 delete[] buffers;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001155
1156 return res;
1157}
1158
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001159status_t Camera2Device::StreamAdapter::release() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001160 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001161 status_t res;
Eino-Ville Talvala02f84572013-04-23 15:16:57 -07001162 ALOGV("%s: Releasing stream %d (%d x %d, format %d)", __FUNCTION__, mId,
1163 mWidth, mHeight, mFormat);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001164 if (mState >= ALLOCATED) {
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001165 res = mHal2Device->ops->release_stream(mHal2Device, mId);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001166 if (res != OK) {
1167 ALOGE("%s: Unable to release stream %d",
1168 __FUNCTION__, mId);
1169 return res;
1170 }
1171 }
1172 if (mState >= CONNECTED) {
1173 res = native_window_api_disconnect(mConsumerInterface.get(),
1174 NATIVE_WINDOW_API_CAMERA);
Igor Murashkina1e5dcc2012-10-02 15:21:31 -07001175
1176 /* this is not an error. if client calling process dies,
1177 the window will also die and all calls to it will return
1178 DEAD_OBJECT, thus it's already "disconnected" */
1179 if (res == DEAD_OBJECT) {
1180 ALOGW("%s: While disconnecting stream %d from native window, the"
1181 " native window died from under us", __FUNCTION__, mId);
1182 }
1183 else if (res != OK) {
1184 ALOGE("%s: Unable to disconnect stream %d from native window (error %d %s)",
1185 __FUNCTION__, mId, res, strerror(-res));
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001186 return res;
1187 }
1188 }
1189 mId = -1;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001190 mState = RELEASED;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001191 return OK;
1192}
1193
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001194status_t Camera2Device::StreamAdapter::setTransform(int transform) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001195 ATRACE_CALL();
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001196 status_t res;
1197 if (mState < CONNECTED) {
1198 ALOGE("%s: Cannot set transform on unconnected stream", __FUNCTION__);
1199 return INVALID_OPERATION;
1200 }
1201 res = native_window_set_buffers_transform(mConsumerInterface.get(),
1202 transform);
1203 if (res != OK) {
1204 ALOGE("%s: Unable to configure stream transform to %x: %s (%d)",
1205 __FUNCTION__, transform, strerror(-res), res);
1206 }
1207 return res;
1208}
1209
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001210status_t Camera2Device::StreamAdapter::dump(int fd,
Igor Murashkinebe3f692012-10-12 16:56:11 -07001211 const Vector<String16>& /*args*/) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001212 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001213 String8 result = String8::format(" Stream %d: %d x %d, format 0x%x\n",
1214 mId, mWidth, mHeight, mFormat);
1215 result.appendFormat(" size %d, usage 0x%x, requested format 0x%x\n",
1216 mSize, mUsage, mFormatRequested);
1217 result.appendFormat(" total buffers: %d, dequeued buffers: %d\n",
1218 mTotalBuffers, mActiveBuffers);
1219 result.appendFormat(" frame count: %d, last timestamp %lld\n",
1220 mFrameCount, mLastTimestamp);
1221 write(fd, result.string(), result.size());
1222 return OK;
1223}
1224
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001225const camera2_stream_ops *Camera2Device::StreamAdapter::getStreamOps() {
1226 return static_cast<camera2_stream_ops *>(this);
1227}
1228
1229ANativeWindow* Camera2Device::StreamAdapter::toANW(
1230 const camera2_stream_ops_t *w) {
1231 return static_cast<const StreamAdapter*>(w)->mConsumerInterface.get();
1232}
1233
1234int Camera2Device::StreamAdapter::dequeue_buffer(const camera2_stream_ops_t *w,
1235 buffer_handle_t** buffer) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001236 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001237 int res;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001238 StreamAdapter* stream =
1239 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
1240 if (stream->mState != ACTIVE) {
1241 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001242 return INVALID_OPERATION;
1243 }
1244
1245 ANativeWindow *a = toANW(w);
1246 ANativeWindowBuffer* anb;
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001247 res = native_window_dequeue_buffer_and_wait(a, &anb);
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001248 if (res != OK) {
1249 ALOGE("Stream %d dequeue: Error from native_window: %s (%d)", stream->mId,
1250 strerror(-res), res);
1251 return res;
1252 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001253
1254 *buffer = &(anb->handle);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001255 stream->mActiveBuffers++;
1256
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001257 ALOGVV("Stream %d dequeue: Buffer %p dequeued", stream->mId, (void*)(**buffer));
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001258 return res;
1259}
1260
1261int Camera2Device::StreamAdapter::enqueue_buffer(const camera2_stream_ops_t* w,
1262 int64_t timestamp,
1263 buffer_handle_t* buffer) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001264 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001265 StreamAdapter *stream =
1266 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001267 stream->mFrameCount++;
1268 ALOGVV("Stream %d enqueue: Frame %d (%p) captured at %lld ns",
James Donga289bf62012-09-05 16:46:36 -07001269 stream->mId, stream->mFrameCount, (void*)(*buffer), timestamp);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001270 int state = stream->mState;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001271 if (state != ACTIVE) {
1272 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1273 return INVALID_OPERATION;
1274 }
1275 ANativeWindow *a = toANW(w);
1276 status_t err;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001277
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001278 err = native_window_set_buffers_timestamp(a, timestamp);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001279 if (err != OK) {
1280 ALOGE("%s: Error setting timestamp on native window: %s (%d)",
1281 __FUNCTION__, strerror(-err), err);
1282 return err;
1283 }
1284 err = a->queueBuffer(a,
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001285 container_of(buffer, ANativeWindowBuffer, handle), -1);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001286 if (err != OK) {
1287 ALOGE("%s: Error queueing buffer to native window: %s (%d)",
1288 __FUNCTION__, strerror(-err), err);
James Dong31d377b2012-08-09 17:43:46 -07001289 return err;
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001290 }
James Dong31d377b2012-08-09 17:43:46 -07001291
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001292 stream->mActiveBuffers--;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001293 stream->mLastTimestamp = timestamp;
James Dong31d377b2012-08-09 17:43:46 -07001294 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001295}
1296
1297int Camera2Device::StreamAdapter::cancel_buffer(const camera2_stream_ops_t* w,
1298 buffer_handle_t* buffer) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001299 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001300 StreamAdapter *stream =
1301 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001302 ALOGVV("Stream %d cancel: Buffer %p",
1303 stream->mId, (void*)(*buffer));
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001304 if (stream->mState != ACTIVE) {
1305 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001306 return INVALID_OPERATION;
1307 }
James Dong31d377b2012-08-09 17:43:46 -07001308
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001309 ANativeWindow *a = toANW(w);
James Dong31d377b2012-08-09 17:43:46 -07001310 int err = a->cancelBuffer(a,
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001311 container_of(buffer, ANativeWindowBuffer, handle), -1);
James Dong31d377b2012-08-09 17:43:46 -07001312 if (err != OK) {
1313 ALOGE("%s: Error canceling buffer to native window: %s (%d)",
1314 __FUNCTION__, strerror(-err), err);
1315 return err;
1316 }
1317
1318 stream->mActiveBuffers--;
1319 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001320}
1321
1322int Camera2Device::StreamAdapter::set_crop(const camera2_stream_ops_t* w,
1323 int left, int top, int right, int bottom) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001324 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001325 int state = static_cast<const StreamAdapter*>(w)->mState;
1326 if (state != ACTIVE) {
1327 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1328 return INVALID_OPERATION;
1329 }
1330 ANativeWindow *a = toANW(w);
1331 android_native_rect_t crop = { left, top, right, bottom };
1332 return native_window_set_crop(a, &crop);
1333}
1334
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001335/**
1336 * Camera2Device::ReprocessStreamAdapter
1337 */
1338
1339#ifndef container_of
1340#define container_of(ptr, type, member) \
1341 (type *)((char*)(ptr) - offsetof(type, member))
1342#endif
1343
1344Camera2Device::ReprocessStreamAdapter::ReprocessStreamAdapter(camera2_device_t *d):
1345 mState(RELEASED),
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001346 mHal2Device(d),
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001347 mId(-1),
1348 mWidth(0), mHeight(0), mFormat(0),
1349 mActiveBuffers(0),
1350 mFrameCount(0)
1351{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001352 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001353 camera2_stream_in_ops::acquire_buffer = acquire_buffer;
1354 camera2_stream_in_ops::release_buffer = release_buffer;
1355}
1356
1357Camera2Device::ReprocessStreamAdapter::~ReprocessStreamAdapter() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001358 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001359 if (mState != RELEASED) {
1360 release();
1361 }
1362}
1363
1364status_t Camera2Device::ReprocessStreamAdapter::connectToDevice(
1365 const sp<StreamAdapter> &outputStream) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001366 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001367 status_t res;
1368 ALOGV("%s: E", __FUNCTION__);
1369
1370 if (mState != RELEASED) return INVALID_OPERATION;
1371 if (outputStream == NULL) {
1372 ALOGE("%s: Null base stream passed to reprocess stream adapter",
1373 __FUNCTION__);
1374 return BAD_VALUE;
1375 }
1376
1377 mBaseStream = outputStream;
1378 mWidth = outputStream->getWidth();
1379 mHeight = outputStream->getHeight();
1380 mFormat = outputStream->getFormat();
1381
1382 ALOGV("%s: New reprocess stream parameters %d x %d, format 0x%x",
1383 __FUNCTION__, mWidth, mHeight, mFormat);
1384
1385 // Allocate device-side stream interface
1386
1387 uint32_t id;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001388 res = mHal2Device->ops->allocate_reprocess_stream_from_stream(mHal2Device,
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001389 outputStream->getId(), getStreamOps(),
1390 &id);
1391 if (res != OK) {
1392 ALOGE("%s: Device reprocess stream allocation failed: %s (%d)",
1393 __FUNCTION__, strerror(-res), res);
1394 return res;
1395 }
1396
1397 ALOGV("%s: Allocated reprocess stream id %d based on stream %d",
1398 __FUNCTION__, id, outputStream->getId());
1399
1400 mId = id;
1401
1402 mState = ACTIVE;
1403
1404 return OK;
1405}
1406
1407status_t Camera2Device::ReprocessStreamAdapter::release() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001408 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001409 status_t res;
1410 ALOGV("%s: Releasing stream %d", __FUNCTION__, mId);
1411 if (mState >= ACTIVE) {
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001412 res = mHal2Device->ops->release_reprocess_stream(mHal2Device, mId);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001413 if (res != OK) {
1414 ALOGE("%s: Unable to release stream %d",
1415 __FUNCTION__, mId);
1416 return res;
1417 }
1418 }
1419
1420 List<QueueEntry>::iterator s;
1421 for (s = mQueue.begin(); s != mQueue.end(); s++) {
1422 sp<BufferReleasedListener> listener = s->releaseListener.promote();
1423 if (listener != 0) listener->onBufferReleased(s->handle);
1424 }
1425 for (s = mInFlightQueue.begin(); s != mInFlightQueue.end(); s++) {
1426 sp<BufferReleasedListener> listener = s->releaseListener.promote();
1427 if (listener != 0) listener->onBufferReleased(s->handle);
1428 }
1429 mQueue.clear();
1430 mInFlightQueue.clear();
1431
1432 mState = RELEASED;
1433 return OK;
1434}
1435
1436status_t Camera2Device::ReprocessStreamAdapter::pushIntoStream(
1437 buffer_handle_t *handle, const wp<BufferReleasedListener> &releaseListener) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001438 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001439 // TODO: Some error checking here would be nice
1440 ALOGV("%s: Pushing buffer %p to stream", __FUNCTION__, (void*)(*handle));
1441
1442 QueueEntry entry;
1443 entry.handle = handle;
1444 entry.releaseListener = releaseListener;
1445 mQueue.push_back(entry);
1446 return OK;
1447}
1448
1449status_t Camera2Device::ReprocessStreamAdapter::dump(int fd,
Igor Murashkinebe3f692012-10-12 16:56:11 -07001450 const Vector<String16>& /*args*/) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001451 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001452 String8 result =
1453 String8::format(" Reprocess stream %d: %d x %d, fmt 0x%x\n",
1454 mId, mWidth, mHeight, mFormat);
1455 result.appendFormat(" acquired buffers: %d\n",
1456 mActiveBuffers);
1457 result.appendFormat(" frame count: %d\n",
1458 mFrameCount);
1459 write(fd, result.string(), result.size());
1460 return OK;
1461}
1462
1463const camera2_stream_in_ops *Camera2Device::ReprocessStreamAdapter::getStreamOps() {
1464 return static_cast<camera2_stream_in_ops *>(this);
1465}
1466
1467int Camera2Device::ReprocessStreamAdapter::acquire_buffer(
1468 const camera2_stream_in_ops_t *w,
1469 buffer_handle_t** buffer) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001470 ATRACE_CALL();
Igor Murashkinebe3f692012-10-12 16:56:11 -07001471
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001472 ReprocessStreamAdapter* stream =
1473 const_cast<ReprocessStreamAdapter*>(
1474 static_cast<const ReprocessStreamAdapter*>(w));
1475 if (stream->mState != ACTIVE) {
1476 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
1477 return INVALID_OPERATION;
1478 }
1479
1480 if (stream->mQueue.empty()) {
1481 *buffer = NULL;
1482 return OK;
1483 }
1484
1485 QueueEntry &entry = *(stream->mQueue.begin());
1486
1487 *buffer = entry.handle;
1488
1489 stream->mInFlightQueue.push_back(entry);
1490 stream->mQueue.erase(stream->mQueue.begin());
1491
1492 stream->mActiveBuffers++;
1493
1494 ALOGV("Stream %d acquire: Buffer %p acquired", stream->mId,
1495 (void*)(**buffer));
1496 return OK;
1497}
1498
1499int Camera2Device::ReprocessStreamAdapter::release_buffer(
1500 const camera2_stream_in_ops_t* w,
1501 buffer_handle_t* buffer) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001502 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001503 ReprocessStreamAdapter *stream =
1504 const_cast<ReprocessStreamAdapter*>(
1505 static_cast<const ReprocessStreamAdapter*>(w) );
1506 stream->mFrameCount++;
1507 ALOGV("Reprocess stream %d release: Frame %d (%p)",
1508 stream->mId, stream->mFrameCount, (void*)*buffer);
1509 int state = stream->mState;
1510 if (state != ACTIVE) {
1511 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1512 return INVALID_OPERATION;
1513 }
1514 stream->mActiveBuffers--;
1515
1516 List<QueueEntry>::iterator s;
1517 for (s = stream->mInFlightQueue.begin(); s != stream->mInFlightQueue.end(); s++) {
1518 if ( s->handle == buffer ) break;
1519 }
1520 if (s == stream->mInFlightQueue.end()) {
1521 ALOGE("%s: Can't find buffer %p in in-flight list!", __FUNCTION__,
1522 buffer);
1523 return INVALID_OPERATION;
1524 }
1525
1526 sp<BufferReleasedListener> listener = s->releaseListener.promote();
1527 if (listener != 0) {
1528 listener->onBufferReleased(s->handle);
1529 } else {
1530 ALOGE("%s: Can't free buffer - missing listener", __FUNCTION__);
1531 }
1532 stream->mInFlightQueue.erase(s);
1533
1534 return OK;
1535}
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001536
1537}; // namespace android