blob: 9b0ad91815417a6b342dbbe6560b2344043a12d3 [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
Kévin PETIT377b2ec2014-02-03 12:35:36 +000028#include <inttypes.h>
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070029#include <utils/Log.h>
Eino-Ville Talvala852c3812012-09-24 09:46:53 -070030#include <utils/Trace.h>
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -070031#include <utils/Timers.h>
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070032#include "Camera2Device.h"
33
34namespace android {
35
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070036Camera2Device::Camera2Device(int id):
37 mId(id),
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -080038 mHal2Device(NULL)
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070039{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -070040 ATRACE_CALL();
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -070041 ALOGV("%s: Created device for camera %d", __FUNCTION__, id);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070042}
43
44Camera2Device::~Camera2Device()
45{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -070046 ATRACE_CALL();
Igor Murashkin8dcdb952012-10-02 16:05:11 -070047 ALOGV("%s: Tearing down for camera id %d", __FUNCTION__, mId);
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -070048 disconnect();
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070049}
50
Igor Murashkin71381052013-03-04 14:53:08 -080051int Camera2Device::getId() const {
52 return mId;
53}
54
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070055status_t Camera2Device::initialize(camera_module_t *module)
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070056{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -070057 ATRACE_CALL();
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -070058 ALOGV("%s: Initializing device for camera %d", __FUNCTION__, mId);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -080059 if (mHal2Device != NULL) {
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -070060 ALOGE("%s: Already initialized!", __FUNCTION__);
61 return INVALID_OPERATION;
62 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -070063
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070064 status_t res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070065 char name[10];
66 snprintf(name, sizeof(name), "%d", mId);
67
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -070068 camera2_device_t *device;
69
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070070 res = module->common.methods->open(&module->common, name,
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -070071 reinterpret_cast<hw_device_t**>(&device));
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070072
73 if (res != OK) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070074 ALOGE("%s: Could not open camera %d: %s (%d)", __FUNCTION__,
75 mId, strerror(-res), res);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070076 return res;
77 }
78
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -070079 if (device->common.version != CAMERA_DEVICE_API_VERSION_2_0) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070080 ALOGE("%s: Could not open camera %d: "
81 "Camera device is not version %x, reports %x instead",
82 __FUNCTION__, mId, CAMERA_DEVICE_API_VERSION_2_0,
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -070083 device->common.version);
84 device->common.close(&device->common);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070085 return BAD_VALUE;
86 }
87
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070088 camera_info info;
89 res = module->get_camera_info(mId, &info);
90 if (res != OK ) return res;
91
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -070092 if (info.device_version != device->common.version) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070093 ALOGE("%s: HAL reporting mismatched camera_info version (%x)"
94 " and device version (%x).", __FUNCTION__,
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -070095 device->common.version, info.device_version);
96 device->common.close(&device->common);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070097 return BAD_VALUE;
98 }
99
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700100 res = mRequestQueue.setConsumerDevice(device);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700101 if (res != OK) {
102 ALOGE("%s: Camera %d: Unable to connect request queue to device: %s (%d)",
103 __FUNCTION__, mId, strerror(-res), res);
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700104 device->common.close(&device->common);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700105 return res;
106 }
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700107 res = mFrameQueue.setProducerDevice(device);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700108 if (res != OK) {
109 ALOGE("%s: Camera %d: Unable to connect frame queue to device: %s (%d)",
110 __FUNCTION__, mId, strerror(-res), res);
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700111 device->common.close(&device->common);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700112 return res;
113 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700114
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700115 res = device->ops->set_notify_callback(device, notificationCallback,
116 NULL);
117 if (res != OK) {
118 ALOGE("%s: Camera %d: Unable to initialize notification callback!",
119 __FUNCTION__, mId);
120 device->common.close(&device->common);
121 return res;
122 }
123
124 mDeviceInfo = info.static_camera_characteristics;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800125 mHal2Device = device;
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700126
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700127 return OK;
128}
129
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700130status_t Camera2Device::disconnect() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700131 ATRACE_CALL();
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700132 status_t res = OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800133 if (mHal2Device) {
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700134 ALOGV("%s: Closing device for camera %d", __FUNCTION__, mId);
135
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800136 int inProgressCount = mHal2Device->ops->get_in_progress_count(mHal2Device);
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700137 if (inProgressCount > 0) {
138 ALOGW("%s: Closing camera device %d with %d requests in flight!",
139 __FUNCTION__, mId, inProgressCount);
140 }
Eino-Ville Talvalac62bb782012-09-24 13:44:07 -0700141 mReprocessStreams.clear();
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700142 mStreams.clear();
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800143 res = mHal2Device->common.close(&mHal2Device->common);
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700144 if (res != OK) {
145 ALOGE("%s: Could not close camera %d: %s (%d)",
146 __FUNCTION__,
147 mId, strerror(-res), res);
148 }
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800149 mHal2Device = NULL;
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700150 ALOGV("%s: Shutdown complete", __FUNCTION__);
151 }
152 return res;
153}
154
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700155status_t Camera2Device::dump(int fd, const Vector<String16>& args) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700156 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700157 String8 result;
Eino-Ville Talvala97197152012-08-06 14:25:19 -0700158 int detailLevel = 0;
159 int n = args.size();
160 String16 detailOption("-d");
161 for (int i = 0; i + 1 < n; i++) {
162 if (args[i] == detailOption) {
163 String8 levelStr(args[i+1]);
164 detailLevel = atoi(levelStr.string());
165 }
166 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700167
Eino-Ville Talvala603b12e2012-08-08 09:25:58 -0700168 result.appendFormat(" Camera2Device[%d] dump (detail level %d):\n",
169 mId, detailLevel);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700170
Eino-Ville Talvala97197152012-08-06 14:25:19 -0700171 if (detailLevel > 0) {
172 result = " Request queue contents:\n";
173 write(fd, result.string(), result.size());
174 mRequestQueue.dump(fd, args);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700175
Eino-Ville Talvala97197152012-08-06 14:25:19 -0700176 result = " Frame queue contents:\n";
177 write(fd, result.string(), result.size());
178 mFrameQueue.dump(fd, args);
179 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700180
181 result = " Active streams:\n";
182 write(fd, result.string(), result.size());
183 for (StreamList::iterator s = mStreams.begin(); s != mStreams.end(); s++) {
184 (*s)->dump(fd, args);
185 }
186
187 result = " HAL device dump:\n";
188 write(fd, result.string(), result.size());
189
190 status_t res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800191 res = mHal2Device->ops->dump(mHal2Device, fd);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700192
193 return res;
194}
195
Igor Murashkinbd02dd12013-02-13 15:53:56 -0800196const CameraMetadata& Camera2Device::info() const {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700197 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700198
199 return mDeviceInfo;
200}
201
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700202status_t Camera2Device::capture(CameraMetadata &request) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700203 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700204 ALOGV("%s: E", __FUNCTION__);
205
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700206 mRequestQueue.enqueue(request.release());
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700207 return OK;
208}
209
Jianing Wei90e59c92014-03-12 18:29:36 -0700210status_t Camera2Device::captureList(const List<const CameraMetadata> &requests) {
211 ATRACE_CALL();
212 ALOGE("%s: Camera2Device burst capture not implemented", __FUNCTION__);
213 return INVALID_OPERATION;
214}
215
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700216
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700217status_t Camera2Device::setStreamingRequest(const CameraMetadata &request) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700218 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700219 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700220 CameraMetadata streamRequest(request);
221 return mRequestQueue.setStreamSlot(streamRequest.release());
222}
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700223
Jianing Wei90e59c92014-03-12 18:29:36 -0700224status_t Camera2Device::setStreamingRequestList(const List<const CameraMetadata> &requests) {
225 ATRACE_CALL();
226 ALOGE("%s, Camera2Device streaming burst not implemented", __FUNCTION__);
227 return INVALID_OPERATION;
228}
229
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700230status_t Camera2Device::clearStreamingRequest() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700231 ATRACE_CALL();
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700232 return mRequestQueue.setStreamSlot(NULL);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700233}
234
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700235status_t Camera2Device::waitUntilRequestReceived(int32_t requestId, nsecs_t timeout) {
236 ATRACE_CALL();
237 return mRequestQueue.waitForDequeue(requestId, timeout);
238}
239
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700240status_t Camera2Device::createStream(sp<ANativeWindow> consumer,
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700241 uint32_t width, uint32_t height, int format, size_t size, int *id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700242 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700243 status_t res;
244 ALOGV("%s: E", __FUNCTION__);
245
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800246 sp<StreamAdapter> stream = new StreamAdapter(mHal2Device);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700247
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700248 res = stream->connectToDevice(consumer, width, height, format, size);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700249 if (res != OK) {
250 ALOGE("%s: Camera %d: Unable to create stream (%d x %d, format %x):"
251 "%s (%d)",
252 __FUNCTION__, mId, width, height, format, strerror(-res), res);
253 return res;
254 }
255
256 *id = stream->getId();
257
258 mStreams.push_back(stream);
259 return OK;
260}
261
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700262status_t Camera2Device::createReprocessStreamFromStream(int outputId, int *id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700263 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700264 status_t res;
265 ALOGV("%s: E", __FUNCTION__);
266
267 bool found = false;
268 StreamList::iterator streamI;
269 for (streamI = mStreams.begin();
270 streamI != mStreams.end(); streamI++) {
271 if ((*streamI)->getId() == outputId) {
272 found = true;
273 break;
274 }
275 }
276 if (!found) {
277 ALOGE("%s: Camera %d: Output stream %d doesn't exist; can't create "
278 "reprocess stream from it!", __FUNCTION__, mId, outputId);
279 return BAD_VALUE;
280 }
281
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800282 sp<ReprocessStreamAdapter> stream = new ReprocessStreamAdapter(mHal2Device);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700283
284 res = stream->connectToDevice((*streamI));
285 if (res != OK) {
286 ALOGE("%s: Camera %d: Unable to create reprocessing stream from "\
287 "stream %d: %s (%d)", __FUNCTION__, mId, outputId,
288 strerror(-res), res);
289 return res;
290 }
291
292 *id = stream->getId();
293
294 mReprocessStreams.push_back(stream);
295 return OK;
296}
297
298
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700299status_t Camera2Device::getStreamInfo(int id,
300 uint32_t *width, uint32_t *height, uint32_t *format) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700301 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700302 ALOGV("%s: E", __FUNCTION__);
303 bool found = false;
304 StreamList::iterator streamI;
305 for (streamI = mStreams.begin();
306 streamI != mStreams.end(); streamI++) {
307 if ((*streamI)->getId() == id) {
308 found = true;
309 break;
310 }
311 }
312 if (!found) {
313 ALOGE("%s: Camera %d: Stream %d does not exist",
314 __FUNCTION__, mId, id);
315 return BAD_VALUE;
316 }
317
318 if (width) *width = (*streamI)->getWidth();
319 if (height) *height = (*streamI)->getHeight();
320 if (format) *format = (*streamI)->getFormat();
321
322 return OK;
323}
324
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -0700325status_t Camera2Device::setStreamTransform(int id,
326 int transform) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700327 ATRACE_CALL();
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -0700328 ALOGV("%s: E", __FUNCTION__);
329 bool found = false;
330 StreamList::iterator streamI;
331 for (streamI = mStreams.begin();
332 streamI != mStreams.end(); streamI++) {
333 if ((*streamI)->getId() == id) {
334 found = true;
335 break;
336 }
337 }
338 if (!found) {
339 ALOGE("%s: Camera %d: Stream %d does not exist",
340 __FUNCTION__, mId, id);
341 return BAD_VALUE;
342 }
343
344 return (*streamI)->setTransform(transform);
345}
346
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700347status_t Camera2Device::deleteStream(int id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700348 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700349 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700350 bool found = false;
351 for (StreamList::iterator streamI = mStreams.begin();
352 streamI != mStreams.end(); streamI++) {
353 if ((*streamI)->getId() == id) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700354 status_t res = (*streamI)->release();
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700355 if (res != OK) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700356 ALOGE("%s: Unable to release stream %d from HAL device: "
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700357 "%s (%d)", __FUNCTION__, id, strerror(-res), res);
358 return res;
359 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700360 mStreams.erase(streamI);
361 found = true;
362 break;
363 }
364 }
365 if (!found) {
366 ALOGE("%s: Camera %d: Unable to find stream %d to delete",
367 __FUNCTION__, mId, id);
368 return BAD_VALUE;
369 }
370 return OK;
371}
372
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700373status_t Camera2Device::deleteReprocessStream(int id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700374 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700375 ALOGV("%s: E", __FUNCTION__);
376 bool found = false;
377 for (ReprocessStreamList::iterator streamI = mReprocessStreams.begin();
378 streamI != mReprocessStreams.end(); streamI++) {
379 if ((*streamI)->getId() == id) {
380 status_t res = (*streamI)->release();
381 if (res != OK) {
382 ALOGE("%s: Unable to release reprocess stream %d from "
383 "HAL device: %s (%d)", __FUNCTION__, id,
384 strerror(-res), res);
385 return res;
386 }
387 mReprocessStreams.erase(streamI);
388 found = true;
389 break;
390 }
391 }
392 if (!found) {
393 ALOGE("%s: Camera %d: Unable to find stream %d to delete",
394 __FUNCTION__, mId, id);
395 return BAD_VALUE;
396 }
397 return OK;
398}
399
400
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700401status_t Camera2Device::createDefaultRequest(int templateId,
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700402 CameraMetadata *request) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700403 ATRACE_CALL();
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700404 status_t err;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700405 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700406 camera_metadata_t *rawRequest;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800407 err = mHal2Device->ops->construct_default_request(
408 mHal2Device, templateId, &rawRequest);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700409 request->acquire(rawRequest);
410 return err;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700411}
412
413status_t Camera2Device::waitUntilDrained() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700414 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700415 static const uint32_t kSleepTime = 50000; // 50 ms
416 static const uint32_t kMaxSleepTime = 10000000; // 10 s
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700417 ALOGV("%s: Camera %d: Starting wait", __FUNCTION__, mId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700418 if (mRequestQueue.getBufferCount() ==
419 CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS) return INVALID_OPERATION;
420
421 // TODO: Set up notifications from HAL, instead of sleeping here
422 uint32_t totalTime = 0;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800423 while (mHal2Device->ops->get_in_progress_count(mHal2Device) > 0) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700424 usleep(kSleepTime);
425 totalTime += kSleepTime;
426 if (totalTime > kMaxSleepTime) {
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700427 ALOGE("%s: Waited %d us, %d requests still in flight", __FUNCTION__,
Alex Rayf0eeb532013-03-17 03:23:18 -0700428 totalTime, mHal2Device->ops->get_in_progress_count(mHal2Device));
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700429 return TIMED_OUT;
430 }
431 }
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700432 ALOGV("%s: Camera %d: HAL is idle", __FUNCTION__, mId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700433 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700434}
435
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700436status_t Camera2Device::setNotifyCallback(NotificationListener *listener) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700437 ATRACE_CALL();
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700438 status_t res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800439 res = mHal2Device->ops->set_notify_callback(mHal2Device, notificationCallback,
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700440 reinterpret_cast<void*>(listener) );
441 if (res != OK) {
442 ALOGE("%s: Unable to set notification callback!", __FUNCTION__);
443 }
444 return res;
445}
446
Eino-Ville Talvala46910bd2013-07-18 19:15:17 -0700447bool Camera2Device::willNotify3A() {
448 return true;
449}
450
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700451void Camera2Device::notificationCallback(int32_t msg_type,
452 int32_t ext1,
453 int32_t ext2,
454 int32_t ext3,
455 void *user) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700456 ATRACE_CALL();
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700457 NotificationListener *listener = reinterpret_cast<NotificationListener*>(user);
458 ALOGV("%s: Notification %d, arguments %d, %d, %d", __FUNCTION__, msg_type,
459 ext1, ext2, ext3);
460 if (listener != NULL) {
461 switch (msg_type) {
462 case CAMERA2_MSG_ERROR:
463 listener->notifyError(ext1, ext2, ext3);
464 break;
465 case CAMERA2_MSG_SHUTTER: {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700466 // TODO: Only needed for camera2 API, which is unsupported
467 // by HAL2 directly.
468 // nsecs_t timestamp = (nsecs_t)ext2 | ((nsecs_t)(ext3) << 32 );
469 // listener->notifyShutter(requestId, timestamp);
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700470 break;
471 }
472 case CAMERA2_MSG_AUTOFOCUS:
473 listener->notifyAutoFocus(ext1, ext2);
474 break;
475 case CAMERA2_MSG_AUTOEXPOSURE:
476 listener->notifyAutoExposure(ext1, ext2);
477 break;
478 case CAMERA2_MSG_AUTOWB:
479 listener->notifyAutoWhitebalance(ext1, ext2);
480 break;
481 default:
482 ALOGE("%s: Unknown notification %d (arguments %d, %d, %d)!",
483 __FUNCTION__, msg_type, ext1, ext2, ext3);
484 }
485 }
486}
487
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -0700488status_t Camera2Device::waitForNextFrame(nsecs_t timeout) {
489 return mFrameQueue.waitForBuffer(timeout);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700490}
491
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700492status_t Camera2Device::getNextFrame(CameraMetadata *frame) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700493 ATRACE_CALL();
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700494 status_t res;
495 camera_metadata_t *rawFrame;
496 res = mFrameQueue.dequeue(&rawFrame);
497 if (rawFrame == NULL) {
498 return NOT_ENOUGH_DATA;
499 } else if (res == OK) {
500 frame->acquire(rawFrame);
501 }
502 return res;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700503}
504
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700505status_t Camera2Device::triggerAutofocus(uint32_t id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700506 ATRACE_CALL();
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700507 status_t res;
508 ALOGV("%s: Triggering autofocus, id %d", __FUNCTION__, id);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800509 res = mHal2Device->ops->trigger_action(mHal2Device,
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700510 CAMERA2_TRIGGER_AUTOFOCUS, id, 0);
511 if (res != OK) {
512 ALOGE("%s: Error triggering autofocus (id %d)",
513 __FUNCTION__, id);
514 }
515 return res;
516}
517
518status_t Camera2Device::triggerCancelAutofocus(uint32_t id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700519 ATRACE_CALL();
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700520 status_t res;
521 ALOGV("%s: Canceling autofocus, id %d", __FUNCTION__, id);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800522 res = mHal2Device->ops->trigger_action(mHal2Device,
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700523 CAMERA2_TRIGGER_CANCEL_AUTOFOCUS, id, 0);
524 if (res != OK) {
525 ALOGE("%s: Error canceling autofocus (id %d)",
526 __FUNCTION__, id);
527 }
528 return res;
529}
530
531status_t Camera2Device::triggerPrecaptureMetering(uint32_t id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700532 ATRACE_CALL();
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700533 status_t res;
534 ALOGV("%s: Triggering precapture metering, id %d", __FUNCTION__, id);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800535 res = mHal2Device->ops->trigger_action(mHal2Device,
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700536 CAMERA2_TRIGGER_PRECAPTURE_METERING, id, 0);
537 if (res != OK) {
538 ALOGE("%s: Error triggering precapture metering (id %d)",
539 __FUNCTION__, id);
540 }
541 return res;
542}
543
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700544status_t Camera2Device::pushReprocessBuffer(int reprocessStreamId,
545 buffer_handle_t *buffer, wp<BufferReleasedListener> listener) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700546 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700547 ALOGV("%s: E", __FUNCTION__);
548 bool found = false;
549 status_t res = OK;
550 for (ReprocessStreamList::iterator streamI = mReprocessStreams.begin();
551 streamI != mReprocessStreams.end(); streamI++) {
552 if ((*streamI)->getId() == reprocessStreamId) {
553 res = (*streamI)->pushIntoStream(buffer, listener);
554 if (res != OK) {
555 ALOGE("%s: Unable to push buffer to reprocess stream %d: %s (%d)",
556 __FUNCTION__, reprocessStreamId, strerror(-res), res);
557 return res;
558 }
559 found = true;
560 break;
561 }
562 }
563 if (!found) {
564 ALOGE("%s: Camera %d: Unable to find reprocess stream %d",
565 __FUNCTION__, mId, reprocessStreamId);
566 res = BAD_VALUE;
567 }
568 return res;
569}
570
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -0700571status_t Camera2Device::flush() {
572 ATRACE_CALL();
573
574 mRequestQueue.clear();
575 return waitUntilDrained();
576}
577
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700578/**
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700579 * Camera2Device::MetadataQueue
580 */
581
582Camera2Device::MetadataQueue::MetadataQueue():
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800583 mHal2Device(NULL),
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700584 mFrameCount(0),
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700585 mLatestRequestId(0),
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700586 mCount(0),
587 mStreamSlotCount(0),
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -0700588 mSignalConsumer(true)
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700589{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700590 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700591 camera2_request_queue_src_ops::dequeue_request = consumer_dequeue;
592 camera2_request_queue_src_ops::request_count = consumer_buffer_count;
593 camera2_request_queue_src_ops::free_request = consumer_free;
594
595 camera2_frame_queue_dst_ops::dequeue_frame = producer_dequeue;
596 camera2_frame_queue_dst_ops::cancel_frame = producer_cancel;
597 camera2_frame_queue_dst_ops::enqueue_frame = producer_enqueue;
598}
599
600Camera2Device::MetadataQueue::~MetadataQueue() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700601 ATRACE_CALL();
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -0700602 clear();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700603}
604
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700605// Connect to camera2 HAL as consumer (input requests/reprocessing)
606status_t Camera2Device::MetadataQueue::setConsumerDevice(camera2_device_t *d) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700607 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700608 status_t res;
609 res = d->ops->set_request_queue_src_ops(d,
610 this);
611 if (res != OK) return res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800612 mHal2Device = d;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700613 return OK;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700614}
615
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700616status_t Camera2Device::MetadataQueue::setProducerDevice(camera2_device_t *d) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700617 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700618 status_t res;
619 res = d->ops->set_frame_queue_dst_ops(d,
620 this);
621 return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700622}
623
624// Real interfaces
625status_t Camera2Device::MetadataQueue::enqueue(camera_metadata_t *buf) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700626 ATRACE_CALL();
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700627 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700628 Mutex::Autolock l(mMutex);
629
630 mCount++;
631 mEntries.push_back(buf);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700632
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700633 return signalConsumerLocked();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700634}
635
636int Camera2Device::MetadataQueue::getBufferCount() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700637 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700638 Mutex::Autolock l(mMutex);
639 if (mStreamSlotCount > 0) {
640 return CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS;
641 }
642 return mCount;
643}
644
645status_t Camera2Device::MetadataQueue::dequeue(camera_metadata_t **buf,
646 bool incrementCount)
647{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700648 ATRACE_CALL();
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700649 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700650 status_t res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700651 Mutex::Autolock l(mMutex);
652
653 if (mCount == 0) {
654 if (mStreamSlotCount == 0) {
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700655 ALOGVV("%s: Empty", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700656 *buf = NULL;
657 mSignalConsumer = true;
658 return OK;
659 }
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700660 ALOGVV("%s: Streaming %d frames to queue", __FUNCTION__,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700661 mStreamSlotCount);
662
663 for (List<camera_metadata_t*>::iterator slotEntry = mStreamSlot.begin();
664 slotEntry != mStreamSlot.end();
665 slotEntry++ ) {
666 size_t entries = get_camera_metadata_entry_count(*slotEntry);
667 size_t dataBytes = get_camera_metadata_data_count(*slotEntry);
668
669 camera_metadata_t *copy =
670 allocate_camera_metadata(entries, dataBytes);
671 append_camera_metadata(copy, *slotEntry);
672 mEntries.push_back(copy);
673 }
674 mCount = mStreamSlotCount;
675 }
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700676 ALOGVV("MetadataQueue: deque (%d buffers)", mCount);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700677 camera_metadata_t *b = *(mEntries.begin());
678 mEntries.erase(mEntries.begin());
679
680 if (incrementCount) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700681 ATRACE_INT("cam2_request", mFrameCount);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700682 camera_metadata_entry_t frameCount;
683 res = find_camera_metadata_entry(b,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700684 ANDROID_REQUEST_FRAME_COUNT,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700685 &frameCount);
686 if (res != OK) {
687 ALOGE("%s: Unable to add frame count: %s (%d)",
688 __FUNCTION__, strerror(-res), res);
689 } else {
690 *frameCount.data.i32 = mFrameCount;
691 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700692 mFrameCount++;
693 }
694
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700695 // Check for request ID, and if present, signal waiters.
696 camera_metadata_entry_t requestId;
697 res = find_camera_metadata_entry(b,
698 ANDROID_REQUEST_ID,
699 &requestId);
700 if (res == OK) {
701 mLatestRequestId = requestId.data.i32[0];
702 mNewRequestId.signal();
703 }
704
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700705 *buf = b;
706 mCount--;
707
708 return OK;
709}
710
711status_t Camera2Device::MetadataQueue::waitForBuffer(nsecs_t timeout)
712{
713 Mutex::Autolock l(mMutex);
714 status_t res;
715 while (mCount == 0) {
716 res = notEmpty.waitRelative(mMutex,timeout);
717 if (res != OK) return res;
718 }
719 return OK;
720}
721
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700722status_t Camera2Device::MetadataQueue::waitForDequeue(int32_t id,
723 nsecs_t timeout) {
724 Mutex::Autolock l(mMutex);
725 status_t res;
726 while (mLatestRequestId != id) {
727 nsecs_t startTime = systemTime();
728
729 res = mNewRequestId.waitRelative(mMutex, timeout);
730 if (res != OK) return res;
731
732 timeout -= (systemTime() - startTime);
733 }
734
735 return OK;
736}
737
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700738status_t Camera2Device::MetadataQueue::setStreamSlot(camera_metadata_t *buf)
739{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700740 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700741 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700742 Mutex::Autolock l(mMutex);
743 if (buf == NULL) {
744 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
745 mStreamSlotCount = 0;
746 return OK;
747 }
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700748 camera_metadata_t *buf2 = clone_camera_metadata(buf);
749 if (!buf2) {
750 ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__);
751 return NO_MEMORY;
752 }
753
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700754 if (mStreamSlotCount > 1) {
755 List<camera_metadata_t*>::iterator deleter = ++mStreamSlot.begin();
756 freeBuffers(++mStreamSlot.begin(), mStreamSlot.end());
757 mStreamSlotCount = 1;
758 }
759 if (mStreamSlotCount == 1) {
760 free_camera_metadata( *(mStreamSlot.begin()) );
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700761 *(mStreamSlot.begin()) = buf2;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700762 } else {
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700763 mStreamSlot.push_front(buf2);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700764 mStreamSlotCount = 1;
765 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700766 return signalConsumerLocked();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700767}
768
769status_t Camera2Device::MetadataQueue::setStreamSlot(
770 const List<camera_metadata_t*> &bufs)
771{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700772 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700773 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700774 Mutex::Autolock l(mMutex);
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700775
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700776 if (mStreamSlotCount > 0) {
777 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
778 }
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700779 mStreamSlotCount = 0;
780 for (List<camera_metadata_t*>::const_iterator r = bufs.begin();
781 r != bufs.end(); r++) {
782 camera_metadata_t *r2 = clone_camera_metadata(*r);
783 if (!r2) {
784 ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__);
785 return NO_MEMORY;
786 }
787 mStreamSlot.push_back(r2);
788 mStreamSlotCount++;
789 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700790 return signalConsumerLocked();
791}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700792
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -0700793status_t Camera2Device::MetadataQueue::clear()
794{
795 ATRACE_CALL();
796 ALOGV("%s: E", __FUNCTION__);
797
798 Mutex::Autolock l(mMutex);
799
800 // Clear streaming slot
801 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
802 mStreamSlotCount = 0;
803
804 // Clear request queue
805 freeBuffers(mEntries.begin(), mEntries.end());
806 mCount = 0;
807 return OK;
808}
809
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700810status_t Camera2Device::MetadataQueue::dump(int fd,
Igor Murashkinebe3f692012-10-12 16:56:11 -0700811 const Vector<String16>& /*args*/) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700812 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700813 String8 result;
814 status_t notLocked;
815 notLocked = mMutex.tryLock();
816 if (notLocked) {
817 result.append(" (Unable to lock queue mutex)\n");
818 }
819 result.appendFormat(" Current frame number: %d\n", mFrameCount);
820 if (mStreamSlotCount == 0) {
821 result.append(" Stream slot: Empty\n");
822 write(fd, result.string(), result.size());
823 } else {
Kévin PETIT377b2ec2014-02-03 12:35:36 +0000824 result.appendFormat(" Stream slot: %zu entries\n",
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700825 mStreamSlot.size());
826 int i = 0;
827 for (List<camera_metadata_t*>::iterator r = mStreamSlot.begin();
828 r != mStreamSlot.end(); r++) {
829 result = String8::format(" Stream slot buffer %d:\n", i);
830 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700831 dump_indented_camera_metadata(*r, fd, 2, 10);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700832 i++;
833 }
834 }
835 if (mEntries.size() == 0) {
836 result = " Main queue is empty\n";
837 write(fd, result.string(), result.size());
838 } else {
Kévin PETIT377b2ec2014-02-03 12:35:36 +0000839 result = String8::format(" Main queue has %zu entries:\n",
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700840 mEntries.size());
841 int i = 0;
842 for (List<camera_metadata_t*>::iterator r = mEntries.begin();
843 r != mEntries.end(); r++) {
844 result = String8::format(" Queue entry %d:\n", i);
845 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700846 dump_indented_camera_metadata(*r, fd, 2, 10);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700847 i++;
848 }
849 }
850
851 if (notLocked == 0) {
852 mMutex.unlock();
853 }
854
855 return OK;
856}
857
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700858status_t Camera2Device::MetadataQueue::signalConsumerLocked() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700859 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700860 status_t res = OK;
861 notEmpty.signal();
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800862 if (mSignalConsumer && mHal2Device != NULL) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700863 mSignalConsumer = false;
864
865 mMutex.unlock();
866 ALOGV("%s: Signaling consumer", __FUNCTION__);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800867 res = mHal2Device->ops->notify_request_queue_not_empty(mHal2Device);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700868 mMutex.lock();
869 }
870 return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700871}
872
873status_t Camera2Device::MetadataQueue::freeBuffers(
874 List<camera_metadata_t*>::iterator start,
875 List<camera_metadata_t*>::iterator end)
876{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700877 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700878 while (start != end) {
879 free_camera_metadata(*start);
880 start = mStreamSlot.erase(start);
881 }
882 return OK;
883}
884
885Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
886 const camera2_request_queue_src_ops_t *q)
887{
888 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
889 return const_cast<MetadataQueue*>(cmq);
890}
891
892Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
893 const camera2_frame_queue_dst_ops_t *q)
894{
895 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
896 return const_cast<MetadataQueue*>(cmq);
897}
898
899int Camera2Device::MetadataQueue::consumer_buffer_count(
900 const camera2_request_queue_src_ops_t *q)
901{
902 MetadataQueue *queue = getInstance(q);
903 return queue->getBufferCount();
904}
905
906int Camera2Device::MetadataQueue::consumer_dequeue(
907 const camera2_request_queue_src_ops_t *q,
908 camera_metadata_t **buffer)
909{
910 MetadataQueue *queue = getInstance(q);
911 return queue->dequeue(buffer, true);
912}
913
914int Camera2Device::MetadataQueue::consumer_free(
915 const camera2_request_queue_src_ops_t *q,
916 camera_metadata_t *old_buffer)
917{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700918 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700919 MetadataQueue *queue = getInstance(q);
Igor Murashkinebe3f692012-10-12 16:56:11 -0700920 (void)queue;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700921 free_camera_metadata(old_buffer);
922 return OK;
923}
924
925int Camera2Device::MetadataQueue::producer_dequeue(
Igor Murashkinebe3f692012-10-12 16:56:11 -0700926 const camera2_frame_queue_dst_ops_t * /*q*/,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700927 size_t entries, size_t bytes,
928 camera_metadata_t **buffer)
929{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700930 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700931 camera_metadata_t *new_buffer =
932 allocate_camera_metadata(entries, bytes);
933 if (new_buffer == NULL) return NO_MEMORY;
934 *buffer = new_buffer;
935 return OK;
936}
937
938int Camera2Device::MetadataQueue::producer_cancel(
Igor Murashkinebe3f692012-10-12 16:56:11 -0700939 const camera2_frame_queue_dst_ops_t * /*q*/,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700940 camera_metadata_t *old_buffer)
941{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700942 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700943 free_camera_metadata(old_buffer);
944 return OK;
945}
946
947int Camera2Device::MetadataQueue::producer_enqueue(
948 const camera2_frame_queue_dst_ops_t *q,
949 camera_metadata_t *filled_buffer)
950{
951 MetadataQueue *queue = getInstance(q);
952 return queue->enqueue(filled_buffer);
953}
954
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700955/**
956 * Camera2Device::StreamAdapter
957 */
958
959#ifndef container_of
960#define container_of(ptr, type, member) \
961 (type *)((char*)(ptr) - offsetof(type, member))
962#endif
963
964Camera2Device::StreamAdapter::StreamAdapter(camera2_device_t *d):
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700965 mState(RELEASED),
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800966 mHal2Device(d),
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700967 mId(-1),
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700968 mWidth(0), mHeight(0), mFormat(0), mSize(0), mUsage(0),
969 mMaxProducerBuffers(0), mMaxConsumerBuffers(0),
970 mTotalBuffers(0),
971 mFormatRequested(0),
972 mActiveBuffers(0),
973 mFrameCount(0),
974 mLastTimestamp(0)
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700975{
976 camera2_stream_ops::dequeue_buffer = dequeue_buffer;
977 camera2_stream_ops::enqueue_buffer = enqueue_buffer;
978 camera2_stream_ops::cancel_buffer = cancel_buffer;
979 camera2_stream_ops::set_crop = set_crop;
980}
981
982Camera2Device::StreamAdapter::~StreamAdapter() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700983 ATRACE_CALL();
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700984 if (mState != RELEASED) {
985 release();
986 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700987}
988
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700989status_t Camera2Device::StreamAdapter::connectToDevice(
990 sp<ANativeWindow> consumer,
991 uint32_t width, uint32_t height, int format, size_t size) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700992 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700993 status_t res;
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700994 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700995
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700996 if (mState != RELEASED) return INVALID_OPERATION;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700997 if (consumer == NULL) {
998 ALOGE("%s: Null consumer passed to stream adapter", __FUNCTION__);
999 return BAD_VALUE;
1000 }
1001
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001002 ALOGV("%s: New stream parameters %d x %d, format 0x%x, size %d",
1003 __FUNCTION__, width, height, format, size);
1004
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001005 mConsumerInterface = consumer;
1006 mWidth = width;
1007 mHeight = height;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001008 mSize = (format == HAL_PIXEL_FORMAT_BLOB) ? size : 0;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001009 mFormatRequested = format;
1010
1011 // Allocate device-side stream interface
1012
1013 uint32_t id;
1014 uint32_t formatActual;
1015 uint32_t usage;
1016 uint32_t maxBuffers = 2;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001017 res = mHal2Device->ops->allocate_stream(mHal2Device,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001018 mWidth, mHeight, mFormatRequested, getStreamOps(),
1019 &id, &formatActual, &usage, &maxBuffers);
1020 if (res != OK) {
1021 ALOGE("%s: Device stream allocation failed: %s (%d)",
1022 __FUNCTION__, strerror(-res), res);
1023 return res;
1024 }
1025
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001026 ALOGV("%s: Allocated stream id %d, actual format 0x%x, "
1027 "usage 0x%x, producer wants %d buffers", __FUNCTION__,
1028 id, formatActual, usage, maxBuffers);
1029
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001030 mId = id;
1031 mFormat = formatActual;
1032 mUsage = usage;
1033 mMaxProducerBuffers = maxBuffers;
1034
1035 mState = ALLOCATED;
1036
1037 // Configure consumer-side ANativeWindow interface
1038 res = native_window_api_connect(mConsumerInterface.get(),
1039 NATIVE_WINDOW_API_CAMERA);
1040 if (res != OK) {
1041 ALOGE("%s: Unable to connect to native window for stream %d",
1042 __FUNCTION__, mId);
1043
1044 return res;
1045 }
1046
1047 mState = CONNECTED;
1048
1049 res = native_window_set_usage(mConsumerInterface.get(), mUsage);
1050 if (res != OK) {
1051 ALOGE("%s: Unable to configure usage %08x for stream %d",
1052 __FUNCTION__, mUsage, mId);
1053 return res;
1054 }
1055
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001056 res = native_window_set_scaling_mode(mConsumerInterface.get(),
1057 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
1058 if (res != OK) {
1059 ALOGE("%s: Unable to configure stream scaling: %s (%d)",
1060 __FUNCTION__, strerror(-res), res);
1061 return res;
1062 }
1063
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001064 res = setTransform(0);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001065 if (res != OK) {
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001066 return res;
1067 }
1068
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001069 if (mFormat == HAL_PIXEL_FORMAT_BLOB) {
1070 res = native_window_set_buffers_geometry(mConsumerInterface.get(),
1071 mSize, 1, mFormat);
1072 if (res != OK) {
1073 ALOGE("%s: Unable to configure compressed stream buffer geometry"
1074 " %d x %d, size %d for stream %d",
1075 __FUNCTION__, mWidth, mHeight, mSize, mId);
1076 return res;
1077 }
1078 } else {
1079 res = native_window_set_buffers_geometry(mConsumerInterface.get(),
1080 mWidth, mHeight, mFormat);
1081 if (res != OK) {
1082 ALOGE("%s: Unable to configure stream buffer geometry"
1083 " %d x %d, format 0x%x for stream %d",
1084 __FUNCTION__, mWidth, mHeight, mFormat, mId);
1085 return res;
1086 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001087 }
1088
1089 int maxConsumerBuffers;
1090 res = mConsumerInterface->query(mConsumerInterface.get(),
1091 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &maxConsumerBuffers);
1092 if (res != OK) {
1093 ALOGE("%s: Unable to query consumer undequeued"
1094 " buffer count for stream %d", __FUNCTION__, mId);
1095 return res;
1096 }
1097 mMaxConsumerBuffers = maxConsumerBuffers;
1098
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001099 ALOGV("%s: Consumer wants %d buffers", __FUNCTION__,
1100 mMaxConsumerBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001101
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001102 mTotalBuffers = mMaxConsumerBuffers + mMaxProducerBuffers;
1103 mActiveBuffers = 0;
1104 mFrameCount = 0;
1105 mLastTimestamp = 0;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001106
1107 res = native_window_set_buffer_count(mConsumerInterface.get(),
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001108 mTotalBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001109 if (res != OK) {
1110 ALOGE("%s: Unable to set buffer count for stream %d",
1111 __FUNCTION__, mId);
1112 return res;
1113 }
1114
1115 // Register allocated buffers with HAL device
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001116 buffer_handle_t *buffers = new buffer_handle_t[mTotalBuffers];
1117 ANativeWindowBuffer **anwBuffers = new ANativeWindowBuffer*[mTotalBuffers];
1118 uint32_t bufferIdx = 0;
1119 for (; bufferIdx < mTotalBuffers; bufferIdx++) {
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001120 res = native_window_dequeue_buffer_and_wait(mConsumerInterface.get(),
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001121 &anwBuffers[bufferIdx]);
1122 if (res != OK) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001123 ALOGE("%s: Unable to dequeue buffer %d for initial registration for "
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001124 "stream %d", __FUNCTION__, bufferIdx, mId);
1125 goto cleanUpBuffers;
1126 }
1127
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001128 buffers[bufferIdx] = anwBuffers[bufferIdx]->handle;
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001129 ALOGV("%s: Buffer %p allocated", __FUNCTION__, (void*)buffers[bufferIdx]);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001130 }
1131
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001132 ALOGV("%s: Registering %d buffers with camera HAL", __FUNCTION__, mTotalBuffers);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001133 res = mHal2Device->ops->register_stream_buffers(mHal2Device,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001134 mId,
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001135 mTotalBuffers,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001136 buffers);
1137 if (res != OK) {
1138 ALOGE("%s: Unable to register buffers with HAL device for stream %d",
1139 __FUNCTION__, mId);
1140 } else {
1141 mState = ACTIVE;
1142 }
1143
1144cleanUpBuffers:
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001145 ALOGV("%s: Cleaning up %d buffers", __FUNCTION__, bufferIdx);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001146 for (uint32_t i = 0; i < bufferIdx; i++) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001147 res = mConsumerInterface->cancelBuffer(mConsumerInterface.get(),
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001148 anwBuffers[i], -1);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001149 if (res != OK) {
1150 ALOGE("%s: Unable to cancel buffer %d after registration",
1151 __FUNCTION__, i);
1152 }
1153 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001154 delete[] anwBuffers;
1155 delete[] buffers;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001156
1157 return res;
1158}
1159
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001160status_t Camera2Device::StreamAdapter::release() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001161 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001162 status_t res;
Eino-Ville Talvala02f84572013-04-23 15:16:57 -07001163 ALOGV("%s: Releasing stream %d (%d x %d, format %d)", __FUNCTION__, mId,
1164 mWidth, mHeight, mFormat);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001165 if (mState >= ALLOCATED) {
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001166 res = mHal2Device->ops->release_stream(mHal2Device, mId);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001167 if (res != OK) {
1168 ALOGE("%s: Unable to release stream %d",
1169 __FUNCTION__, mId);
1170 return res;
1171 }
1172 }
1173 if (mState >= CONNECTED) {
1174 res = native_window_api_disconnect(mConsumerInterface.get(),
1175 NATIVE_WINDOW_API_CAMERA);
Igor Murashkina1e5dcc2012-10-02 15:21:31 -07001176
1177 /* this is not an error. if client calling process dies,
1178 the window will also die and all calls to it will return
1179 DEAD_OBJECT, thus it's already "disconnected" */
1180 if (res == DEAD_OBJECT) {
1181 ALOGW("%s: While disconnecting stream %d from native window, the"
1182 " native window died from under us", __FUNCTION__, mId);
1183 }
1184 else if (res != OK) {
1185 ALOGE("%s: Unable to disconnect stream %d from native window (error %d %s)",
1186 __FUNCTION__, mId, res, strerror(-res));
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001187 return res;
1188 }
1189 }
1190 mId = -1;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001191 mState = RELEASED;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001192 return OK;
1193}
1194
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001195status_t Camera2Device::StreamAdapter::setTransform(int transform) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001196 ATRACE_CALL();
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001197 status_t res;
1198 if (mState < CONNECTED) {
1199 ALOGE("%s: Cannot set transform on unconnected stream", __FUNCTION__);
1200 return INVALID_OPERATION;
1201 }
1202 res = native_window_set_buffers_transform(mConsumerInterface.get(),
1203 transform);
1204 if (res != OK) {
1205 ALOGE("%s: Unable to configure stream transform to %x: %s (%d)",
1206 __FUNCTION__, transform, strerror(-res), res);
1207 }
1208 return res;
1209}
1210
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001211status_t Camera2Device::StreamAdapter::dump(int fd,
Igor Murashkinebe3f692012-10-12 16:56:11 -07001212 const Vector<String16>& /*args*/) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001213 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001214 String8 result = String8::format(" Stream %d: %d x %d, format 0x%x\n",
1215 mId, mWidth, mHeight, mFormat);
Kévin PETIT377b2ec2014-02-03 12:35:36 +00001216 result.appendFormat(" size %zu, usage 0x%x, requested format 0x%x\n",
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001217 mSize, mUsage, mFormatRequested);
1218 result.appendFormat(" total buffers: %d, dequeued buffers: %d\n",
1219 mTotalBuffers, mActiveBuffers);
Kévin PETIT377b2ec2014-02-03 12:35:36 +00001220 result.appendFormat(" frame count: %d, last timestamp %" PRId64 "\n",
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001221 mFrameCount, mLastTimestamp);
1222 write(fd, result.string(), result.size());
1223 return OK;
1224}
1225
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001226const camera2_stream_ops *Camera2Device::StreamAdapter::getStreamOps() {
1227 return static_cast<camera2_stream_ops *>(this);
1228}
1229
1230ANativeWindow* Camera2Device::StreamAdapter::toANW(
1231 const camera2_stream_ops_t *w) {
1232 return static_cast<const StreamAdapter*>(w)->mConsumerInterface.get();
1233}
1234
1235int Camera2Device::StreamAdapter::dequeue_buffer(const camera2_stream_ops_t *w,
1236 buffer_handle_t** buffer) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001237 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001238 int res;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001239 StreamAdapter* stream =
1240 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
1241 if (stream->mState != ACTIVE) {
1242 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001243 return INVALID_OPERATION;
1244 }
1245
1246 ANativeWindow *a = toANW(w);
1247 ANativeWindowBuffer* anb;
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001248 res = native_window_dequeue_buffer_and_wait(a, &anb);
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001249 if (res != OK) {
1250 ALOGE("Stream %d dequeue: Error from native_window: %s (%d)", stream->mId,
1251 strerror(-res), res);
1252 return res;
1253 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001254
1255 *buffer = &(anb->handle);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001256 stream->mActiveBuffers++;
1257
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001258 ALOGVV("Stream %d dequeue: Buffer %p dequeued", stream->mId, (void*)(**buffer));
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001259 return res;
1260}
1261
1262int Camera2Device::StreamAdapter::enqueue_buffer(const camera2_stream_ops_t* w,
1263 int64_t timestamp,
1264 buffer_handle_t* buffer) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001265 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001266 StreamAdapter *stream =
1267 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001268 stream->mFrameCount++;
1269 ALOGVV("Stream %d enqueue: Frame %d (%p) captured at %lld ns",
James Donga289bf62012-09-05 16:46:36 -07001270 stream->mId, stream->mFrameCount, (void*)(*buffer), timestamp);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001271 int state = stream->mState;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001272 if (state != ACTIVE) {
1273 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1274 return INVALID_OPERATION;
1275 }
1276 ANativeWindow *a = toANW(w);
1277 status_t err;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001278
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001279 err = native_window_set_buffers_timestamp(a, timestamp);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001280 if (err != OK) {
1281 ALOGE("%s: Error setting timestamp on native window: %s (%d)",
1282 __FUNCTION__, strerror(-err), err);
1283 return err;
1284 }
1285 err = a->queueBuffer(a,
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001286 container_of(buffer, ANativeWindowBuffer, handle), -1);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001287 if (err != OK) {
1288 ALOGE("%s: Error queueing buffer to native window: %s (%d)",
1289 __FUNCTION__, strerror(-err), err);
James Dong31d377b2012-08-09 17:43:46 -07001290 return err;
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001291 }
James Dong31d377b2012-08-09 17:43:46 -07001292
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001293 stream->mActiveBuffers--;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001294 stream->mLastTimestamp = timestamp;
James Dong31d377b2012-08-09 17:43:46 -07001295 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001296}
1297
1298int Camera2Device::StreamAdapter::cancel_buffer(const camera2_stream_ops_t* w,
1299 buffer_handle_t* buffer) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001300 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001301 StreamAdapter *stream =
1302 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001303 ALOGVV("Stream %d cancel: Buffer %p",
1304 stream->mId, (void*)(*buffer));
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001305 if (stream->mState != ACTIVE) {
1306 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001307 return INVALID_OPERATION;
1308 }
James Dong31d377b2012-08-09 17:43:46 -07001309
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001310 ANativeWindow *a = toANW(w);
James Dong31d377b2012-08-09 17:43:46 -07001311 int err = a->cancelBuffer(a,
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001312 container_of(buffer, ANativeWindowBuffer, handle), -1);
James Dong31d377b2012-08-09 17:43:46 -07001313 if (err != OK) {
1314 ALOGE("%s: Error canceling buffer to native window: %s (%d)",
1315 __FUNCTION__, strerror(-err), err);
1316 return err;
1317 }
1318
1319 stream->mActiveBuffers--;
1320 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001321}
1322
1323int Camera2Device::StreamAdapter::set_crop(const camera2_stream_ops_t* w,
1324 int left, int top, int right, int bottom) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001325 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001326 int state = static_cast<const StreamAdapter*>(w)->mState;
1327 if (state != ACTIVE) {
1328 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1329 return INVALID_OPERATION;
1330 }
1331 ANativeWindow *a = toANW(w);
1332 android_native_rect_t crop = { left, top, right, bottom };
1333 return native_window_set_crop(a, &crop);
1334}
1335
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001336/**
1337 * Camera2Device::ReprocessStreamAdapter
1338 */
1339
1340#ifndef container_of
1341#define container_of(ptr, type, member) \
1342 (type *)((char*)(ptr) - offsetof(type, member))
1343#endif
1344
1345Camera2Device::ReprocessStreamAdapter::ReprocessStreamAdapter(camera2_device_t *d):
1346 mState(RELEASED),
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001347 mHal2Device(d),
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001348 mId(-1),
1349 mWidth(0), mHeight(0), mFormat(0),
1350 mActiveBuffers(0),
1351 mFrameCount(0)
1352{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001353 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001354 camera2_stream_in_ops::acquire_buffer = acquire_buffer;
1355 camera2_stream_in_ops::release_buffer = release_buffer;
1356}
1357
1358Camera2Device::ReprocessStreamAdapter::~ReprocessStreamAdapter() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001359 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001360 if (mState != RELEASED) {
1361 release();
1362 }
1363}
1364
1365status_t Camera2Device::ReprocessStreamAdapter::connectToDevice(
1366 const sp<StreamAdapter> &outputStream) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001367 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001368 status_t res;
1369 ALOGV("%s: E", __FUNCTION__);
1370
1371 if (mState != RELEASED) return INVALID_OPERATION;
1372 if (outputStream == NULL) {
1373 ALOGE("%s: Null base stream passed to reprocess stream adapter",
1374 __FUNCTION__);
1375 return BAD_VALUE;
1376 }
1377
1378 mBaseStream = outputStream;
1379 mWidth = outputStream->getWidth();
1380 mHeight = outputStream->getHeight();
1381 mFormat = outputStream->getFormat();
1382
1383 ALOGV("%s: New reprocess stream parameters %d x %d, format 0x%x",
1384 __FUNCTION__, mWidth, mHeight, mFormat);
1385
1386 // Allocate device-side stream interface
1387
1388 uint32_t id;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001389 res = mHal2Device->ops->allocate_reprocess_stream_from_stream(mHal2Device,
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001390 outputStream->getId(), getStreamOps(),
1391 &id);
1392 if (res != OK) {
1393 ALOGE("%s: Device reprocess stream allocation failed: %s (%d)",
1394 __FUNCTION__, strerror(-res), res);
1395 return res;
1396 }
1397
1398 ALOGV("%s: Allocated reprocess stream id %d based on stream %d",
1399 __FUNCTION__, id, outputStream->getId());
1400
1401 mId = id;
1402
1403 mState = ACTIVE;
1404
1405 return OK;
1406}
1407
1408status_t Camera2Device::ReprocessStreamAdapter::release() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001409 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001410 status_t res;
1411 ALOGV("%s: Releasing stream %d", __FUNCTION__, mId);
1412 if (mState >= ACTIVE) {
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001413 res = mHal2Device->ops->release_reprocess_stream(mHal2Device, mId);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001414 if (res != OK) {
1415 ALOGE("%s: Unable to release stream %d",
1416 __FUNCTION__, mId);
1417 return res;
1418 }
1419 }
1420
1421 List<QueueEntry>::iterator s;
1422 for (s = mQueue.begin(); s != mQueue.end(); s++) {
1423 sp<BufferReleasedListener> listener = s->releaseListener.promote();
1424 if (listener != 0) listener->onBufferReleased(s->handle);
1425 }
1426 for (s = mInFlightQueue.begin(); s != mInFlightQueue.end(); s++) {
1427 sp<BufferReleasedListener> listener = s->releaseListener.promote();
1428 if (listener != 0) listener->onBufferReleased(s->handle);
1429 }
1430 mQueue.clear();
1431 mInFlightQueue.clear();
1432
1433 mState = RELEASED;
1434 return OK;
1435}
1436
1437status_t Camera2Device::ReprocessStreamAdapter::pushIntoStream(
1438 buffer_handle_t *handle, const wp<BufferReleasedListener> &releaseListener) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001439 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001440 // TODO: Some error checking here would be nice
1441 ALOGV("%s: Pushing buffer %p to stream", __FUNCTION__, (void*)(*handle));
1442
1443 QueueEntry entry;
1444 entry.handle = handle;
1445 entry.releaseListener = releaseListener;
1446 mQueue.push_back(entry);
1447 return OK;
1448}
1449
1450status_t Camera2Device::ReprocessStreamAdapter::dump(int fd,
Igor Murashkinebe3f692012-10-12 16:56:11 -07001451 const Vector<String16>& /*args*/) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001452 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001453 String8 result =
1454 String8::format(" Reprocess stream %d: %d x %d, fmt 0x%x\n",
1455 mId, mWidth, mHeight, mFormat);
1456 result.appendFormat(" acquired buffers: %d\n",
1457 mActiveBuffers);
1458 result.appendFormat(" frame count: %d\n",
1459 mFrameCount);
1460 write(fd, result.string(), result.size());
1461 return OK;
1462}
1463
1464const camera2_stream_in_ops *Camera2Device::ReprocessStreamAdapter::getStreamOps() {
1465 return static_cast<camera2_stream_in_ops *>(this);
1466}
1467
1468int Camera2Device::ReprocessStreamAdapter::acquire_buffer(
1469 const camera2_stream_in_ops_t *w,
1470 buffer_handle_t** buffer) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001471 ATRACE_CALL();
Igor Murashkinebe3f692012-10-12 16:56:11 -07001472
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001473 ReprocessStreamAdapter* stream =
1474 const_cast<ReprocessStreamAdapter*>(
1475 static_cast<const ReprocessStreamAdapter*>(w));
1476 if (stream->mState != ACTIVE) {
1477 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
1478 return INVALID_OPERATION;
1479 }
1480
1481 if (stream->mQueue.empty()) {
1482 *buffer = NULL;
1483 return OK;
1484 }
1485
1486 QueueEntry &entry = *(stream->mQueue.begin());
1487
1488 *buffer = entry.handle;
1489
1490 stream->mInFlightQueue.push_back(entry);
1491 stream->mQueue.erase(stream->mQueue.begin());
1492
1493 stream->mActiveBuffers++;
1494
1495 ALOGV("Stream %d acquire: Buffer %p acquired", stream->mId,
1496 (void*)(**buffer));
1497 return OK;
1498}
1499
1500int Camera2Device::ReprocessStreamAdapter::release_buffer(
1501 const camera2_stream_in_ops_t* w,
1502 buffer_handle_t* buffer) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001503 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001504 ReprocessStreamAdapter *stream =
1505 const_cast<ReprocessStreamAdapter*>(
1506 static_cast<const ReprocessStreamAdapter*>(w) );
1507 stream->mFrameCount++;
1508 ALOGV("Reprocess stream %d release: Frame %d (%p)",
1509 stream->mId, stream->mFrameCount, (void*)*buffer);
1510 int state = stream->mState;
1511 if (state != ACTIVE) {
1512 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1513 return INVALID_OPERATION;
1514 }
1515 stream->mActiveBuffers--;
1516
1517 List<QueueEntry>::iterator s;
1518 for (s = stream->mInFlightQueue.begin(); s != stream->mInFlightQueue.end(); s++) {
1519 if ( s->handle == buffer ) break;
1520 }
1521 if (s == stream->mInFlightQueue.end()) {
1522 ALOGE("%s: Can't find buffer %p in in-flight list!", __FUNCTION__,
1523 buffer);
1524 return INVALID_OPERATION;
1525 }
1526
1527 sp<BufferReleasedListener> listener = s->releaseListener.promote();
1528 if (listener != 0) {
1529 listener->onBufferReleased(s->handle);
1530 } else {
1531 ALOGE("%s: Can't free buffer - missing listener", __FUNCTION__);
1532 }
1533 stream->mInFlightQueue.erase(s);
1534
1535 return OK;
1536}
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001537
1538}; // namespace android