blob: f60ca98bc33a70ec41c3e66227021ed859a23142 [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
210
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700211status_t Camera2Device::setStreamingRequest(const CameraMetadata &request) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700212 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700213 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700214 CameraMetadata streamRequest(request);
215 return mRequestQueue.setStreamSlot(streamRequest.release());
216}
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700217
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700218status_t Camera2Device::clearStreamingRequest() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700219 ATRACE_CALL();
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700220 return mRequestQueue.setStreamSlot(NULL);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700221}
222
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700223status_t Camera2Device::waitUntilRequestReceived(int32_t requestId, nsecs_t timeout) {
224 ATRACE_CALL();
225 return mRequestQueue.waitForDequeue(requestId, timeout);
226}
227
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700228status_t Camera2Device::createStream(sp<ANativeWindow> consumer,
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700229 uint32_t width, uint32_t height, int format, size_t size, int *id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700230 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700231 status_t res;
232 ALOGV("%s: E", __FUNCTION__);
233
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800234 sp<StreamAdapter> stream = new StreamAdapter(mHal2Device);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700235
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700236 res = stream->connectToDevice(consumer, width, height, format, size);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700237 if (res != OK) {
238 ALOGE("%s: Camera %d: Unable to create stream (%d x %d, format %x):"
239 "%s (%d)",
240 __FUNCTION__, mId, width, height, format, strerror(-res), res);
241 return res;
242 }
243
244 *id = stream->getId();
245
246 mStreams.push_back(stream);
247 return OK;
248}
249
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700250status_t Camera2Device::createReprocessStreamFromStream(int outputId, int *id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700251 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700252 status_t res;
253 ALOGV("%s: E", __FUNCTION__);
254
255 bool found = false;
256 StreamList::iterator streamI;
257 for (streamI = mStreams.begin();
258 streamI != mStreams.end(); streamI++) {
259 if ((*streamI)->getId() == outputId) {
260 found = true;
261 break;
262 }
263 }
264 if (!found) {
265 ALOGE("%s: Camera %d: Output stream %d doesn't exist; can't create "
266 "reprocess stream from it!", __FUNCTION__, mId, outputId);
267 return BAD_VALUE;
268 }
269
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800270 sp<ReprocessStreamAdapter> stream = new ReprocessStreamAdapter(mHal2Device);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700271
272 res = stream->connectToDevice((*streamI));
273 if (res != OK) {
274 ALOGE("%s: Camera %d: Unable to create reprocessing stream from "\
275 "stream %d: %s (%d)", __FUNCTION__, mId, outputId,
276 strerror(-res), res);
277 return res;
278 }
279
280 *id = stream->getId();
281
282 mReprocessStreams.push_back(stream);
283 return OK;
284}
285
286
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700287status_t Camera2Device::getStreamInfo(int id,
288 uint32_t *width, uint32_t *height, uint32_t *format) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700289 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700290 ALOGV("%s: E", __FUNCTION__);
291 bool found = false;
292 StreamList::iterator streamI;
293 for (streamI = mStreams.begin();
294 streamI != mStreams.end(); streamI++) {
295 if ((*streamI)->getId() == id) {
296 found = true;
297 break;
298 }
299 }
300 if (!found) {
301 ALOGE("%s: Camera %d: Stream %d does not exist",
302 __FUNCTION__, mId, id);
303 return BAD_VALUE;
304 }
305
306 if (width) *width = (*streamI)->getWidth();
307 if (height) *height = (*streamI)->getHeight();
308 if (format) *format = (*streamI)->getFormat();
309
310 return OK;
311}
312
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -0700313status_t Camera2Device::setStreamTransform(int id,
314 int transform) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700315 ATRACE_CALL();
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -0700316 ALOGV("%s: E", __FUNCTION__);
317 bool found = false;
318 StreamList::iterator streamI;
319 for (streamI = mStreams.begin();
320 streamI != mStreams.end(); streamI++) {
321 if ((*streamI)->getId() == id) {
322 found = true;
323 break;
324 }
325 }
326 if (!found) {
327 ALOGE("%s: Camera %d: Stream %d does not exist",
328 __FUNCTION__, mId, id);
329 return BAD_VALUE;
330 }
331
332 return (*streamI)->setTransform(transform);
333}
334
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700335status_t Camera2Device::deleteStream(int id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700336 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700337 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700338 bool found = false;
339 for (StreamList::iterator streamI = mStreams.begin();
340 streamI != mStreams.end(); streamI++) {
341 if ((*streamI)->getId() == id) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700342 status_t res = (*streamI)->release();
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700343 if (res != OK) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700344 ALOGE("%s: Unable to release stream %d from HAL device: "
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700345 "%s (%d)", __FUNCTION__, id, strerror(-res), res);
346 return res;
347 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700348 mStreams.erase(streamI);
349 found = true;
350 break;
351 }
352 }
353 if (!found) {
354 ALOGE("%s: Camera %d: Unable to find stream %d to delete",
355 __FUNCTION__, mId, id);
356 return BAD_VALUE;
357 }
358 return OK;
359}
360
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700361status_t Camera2Device::deleteReprocessStream(int id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700362 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700363 ALOGV("%s: E", __FUNCTION__);
364 bool found = false;
365 for (ReprocessStreamList::iterator streamI = mReprocessStreams.begin();
366 streamI != mReprocessStreams.end(); streamI++) {
367 if ((*streamI)->getId() == id) {
368 status_t res = (*streamI)->release();
369 if (res != OK) {
370 ALOGE("%s: Unable to release reprocess stream %d from "
371 "HAL device: %s (%d)", __FUNCTION__, id,
372 strerror(-res), res);
373 return res;
374 }
375 mReprocessStreams.erase(streamI);
376 found = true;
377 break;
378 }
379 }
380 if (!found) {
381 ALOGE("%s: Camera %d: Unable to find stream %d to delete",
382 __FUNCTION__, mId, id);
383 return BAD_VALUE;
384 }
385 return OK;
386}
387
388
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700389status_t Camera2Device::createDefaultRequest(int templateId,
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700390 CameraMetadata *request) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700391 ATRACE_CALL();
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700392 status_t err;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700393 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700394 camera_metadata_t *rawRequest;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800395 err = mHal2Device->ops->construct_default_request(
396 mHal2Device, templateId, &rawRequest);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700397 request->acquire(rawRequest);
398 return err;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700399}
400
401status_t Camera2Device::waitUntilDrained() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700402 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700403 static const uint32_t kSleepTime = 50000; // 50 ms
404 static const uint32_t kMaxSleepTime = 10000000; // 10 s
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700405 ALOGV("%s: Camera %d: Starting wait", __FUNCTION__, mId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700406 if (mRequestQueue.getBufferCount() ==
407 CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS) return INVALID_OPERATION;
408
409 // TODO: Set up notifications from HAL, instead of sleeping here
410 uint32_t totalTime = 0;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800411 while (mHal2Device->ops->get_in_progress_count(mHal2Device) > 0) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700412 usleep(kSleepTime);
413 totalTime += kSleepTime;
414 if (totalTime > kMaxSleepTime) {
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700415 ALOGE("%s: Waited %d us, %d requests still in flight", __FUNCTION__,
Alex Rayf0eeb532013-03-17 03:23:18 -0700416 totalTime, mHal2Device->ops->get_in_progress_count(mHal2Device));
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700417 return TIMED_OUT;
418 }
419 }
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700420 ALOGV("%s: Camera %d: HAL is idle", __FUNCTION__, mId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700421 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700422}
423
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700424status_t Camera2Device::setNotifyCallback(NotificationListener *listener) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700425 ATRACE_CALL();
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700426 status_t res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800427 res = mHal2Device->ops->set_notify_callback(mHal2Device, notificationCallback,
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700428 reinterpret_cast<void*>(listener) );
429 if (res != OK) {
430 ALOGE("%s: Unable to set notification callback!", __FUNCTION__);
431 }
432 return res;
433}
434
Eino-Ville Talvala46910bd2013-07-18 19:15:17 -0700435bool Camera2Device::willNotify3A() {
436 return true;
437}
438
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700439void Camera2Device::notificationCallback(int32_t msg_type,
440 int32_t ext1,
441 int32_t ext2,
442 int32_t ext3,
443 void *user) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700444 ATRACE_CALL();
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700445 NotificationListener *listener = reinterpret_cast<NotificationListener*>(user);
446 ALOGV("%s: Notification %d, arguments %d, %d, %d", __FUNCTION__, msg_type,
447 ext1, ext2, ext3);
448 if (listener != NULL) {
449 switch (msg_type) {
450 case CAMERA2_MSG_ERROR:
451 listener->notifyError(ext1, ext2, ext3);
452 break;
453 case CAMERA2_MSG_SHUTTER: {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700454 // TODO: Only needed for camera2 API, which is unsupported
455 // by HAL2 directly.
456 // nsecs_t timestamp = (nsecs_t)ext2 | ((nsecs_t)(ext3) << 32 );
457 // listener->notifyShutter(requestId, timestamp);
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700458 break;
459 }
460 case CAMERA2_MSG_AUTOFOCUS:
461 listener->notifyAutoFocus(ext1, ext2);
462 break;
463 case CAMERA2_MSG_AUTOEXPOSURE:
464 listener->notifyAutoExposure(ext1, ext2);
465 break;
466 case CAMERA2_MSG_AUTOWB:
467 listener->notifyAutoWhitebalance(ext1, ext2);
468 break;
469 default:
470 ALOGE("%s: Unknown notification %d (arguments %d, %d, %d)!",
471 __FUNCTION__, msg_type, ext1, ext2, ext3);
472 }
473 }
474}
475
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -0700476status_t Camera2Device::waitForNextFrame(nsecs_t timeout) {
477 return mFrameQueue.waitForBuffer(timeout);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700478}
479
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700480status_t Camera2Device::getNextFrame(CameraMetadata *frame) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700481 ATRACE_CALL();
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700482 status_t res;
483 camera_metadata_t *rawFrame;
484 res = mFrameQueue.dequeue(&rawFrame);
485 if (rawFrame == NULL) {
486 return NOT_ENOUGH_DATA;
487 } else if (res == OK) {
488 frame->acquire(rawFrame);
489 }
490 return res;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700491}
492
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700493status_t Camera2Device::triggerAutofocus(uint32_t id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700494 ATRACE_CALL();
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700495 status_t res;
496 ALOGV("%s: Triggering autofocus, id %d", __FUNCTION__, id);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800497 res = mHal2Device->ops->trigger_action(mHal2Device,
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700498 CAMERA2_TRIGGER_AUTOFOCUS, id, 0);
499 if (res != OK) {
500 ALOGE("%s: Error triggering autofocus (id %d)",
501 __FUNCTION__, id);
502 }
503 return res;
504}
505
506status_t Camera2Device::triggerCancelAutofocus(uint32_t id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700507 ATRACE_CALL();
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700508 status_t res;
509 ALOGV("%s: Canceling autofocus, id %d", __FUNCTION__, id);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800510 res = mHal2Device->ops->trigger_action(mHal2Device,
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700511 CAMERA2_TRIGGER_CANCEL_AUTOFOCUS, id, 0);
512 if (res != OK) {
513 ALOGE("%s: Error canceling autofocus (id %d)",
514 __FUNCTION__, id);
515 }
516 return res;
517}
518
519status_t Camera2Device::triggerPrecaptureMetering(uint32_t id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700520 ATRACE_CALL();
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700521 status_t res;
522 ALOGV("%s: Triggering precapture metering, id %d", __FUNCTION__, id);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800523 res = mHal2Device->ops->trigger_action(mHal2Device,
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700524 CAMERA2_TRIGGER_PRECAPTURE_METERING, id, 0);
525 if (res != OK) {
526 ALOGE("%s: Error triggering precapture metering (id %d)",
527 __FUNCTION__, id);
528 }
529 return res;
530}
531
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700532status_t Camera2Device::pushReprocessBuffer(int reprocessStreamId,
533 buffer_handle_t *buffer, wp<BufferReleasedListener> listener) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700534 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700535 ALOGV("%s: E", __FUNCTION__);
536 bool found = false;
537 status_t res = OK;
538 for (ReprocessStreamList::iterator streamI = mReprocessStreams.begin();
539 streamI != mReprocessStreams.end(); streamI++) {
540 if ((*streamI)->getId() == reprocessStreamId) {
541 res = (*streamI)->pushIntoStream(buffer, listener);
542 if (res != OK) {
543 ALOGE("%s: Unable to push buffer to reprocess stream %d: %s (%d)",
544 __FUNCTION__, reprocessStreamId, strerror(-res), res);
545 return res;
546 }
547 found = true;
548 break;
549 }
550 }
551 if (!found) {
552 ALOGE("%s: Camera %d: Unable to find reprocess stream %d",
553 __FUNCTION__, mId, reprocessStreamId);
554 res = BAD_VALUE;
555 }
556 return res;
557}
558
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -0700559status_t Camera2Device::flush() {
560 ATRACE_CALL();
561
562 mRequestQueue.clear();
563 return waitUntilDrained();
564}
565
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700566/**
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700567 * Camera2Device::MetadataQueue
568 */
569
570Camera2Device::MetadataQueue::MetadataQueue():
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800571 mHal2Device(NULL),
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700572 mFrameCount(0),
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700573 mLatestRequestId(0),
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700574 mCount(0),
575 mStreamSlotCount(0),
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -0700576 mSignalConsumer(true)
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700577{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700578 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700579 camera2_request_queue_src_ops::dequeue_request = consumer_dequeue;
580 camera2_request_queue_src_ops::request_count = consumer_buffer_count;
581 camera2_request_queue_src_ops::free_request = consumer_free;
582
583 camera2_frame_queue_dst_ops::dequeue_frame = producer_dequeue;
584 camera2_frame_queue_dst_ops::cancel_frame = producer_cancel;
585 camera2_frame_queue_dst_ops::enqueue_frame = producer_enqueue;
586}
587
588Camera2Device::MetadataQueue::~MetadataQueue() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700589 ATRACE_CALL();
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -0700590 clear();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700591}
592
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700593// Connect to camera2 HAL as consumer (input requests/reprocessing)
594status_t Camera2Device::MetadataQueue::setConsumerDevice(camera2_device_t *d) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700595 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700596 status_t res;
597 res = d->ops->set_request_queue_src_ops(d,
598 this);
599 if (res != OK) return res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800600 mHal2Device = d;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700601 return OK;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700602}
603
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700604status_t Camera2Device::MetadataQueue::setProducerDevice(camera2_device_t *d) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700605 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700606 status_t res;
607 res = d->ops->set_frame_queue_dst_ops(d,
608 this);
609 return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700610}
611
612// Real interfaces
613status_t Camera2Device::MetadataQueue::enqueue(camera_metadata_t *buf) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700614 ATRACE_CALL();
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700615 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700616 Mutex::Autolock l(mMutex);
617
618 mCount++;
619 mEntries.push_back(buf);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700620
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700621 return signalConsumerLocked();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700622}
623
624int Camera2Device::MetadataQueue::getBufferCount() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700625 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700626 Mutex::Autolock l(mMutex);
627 if (mStreamSlotCount > 0) {
628 return CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS;
629 }
630 return mCount;
631}
632
633status_t Camera2Device::MetadataQueue::dequeue(camera_metadata_t **buf,
634 bool incrementCount)
635{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700636 ATRACE_CALL();
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700637 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700638 status_t res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700639 Mutex::Autolock l(mMutex);
640
641 if (mCount == 0) {
642 if (mStreamSlotCount == 0) {
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700643 ALOGVV("%s: Empty", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700644 *buf = NULL;
645 mSignalConsumer = true;
646 return OK;
647 }
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700648 ALOGVV("%s: Streaming %d frames to queue", __FUNCTION__,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700649 mStreamSlotCount);
650
651 for (List<camera_metadata_t*>::iterator slotEntry = mStreamSlot.begin();
652 slotEntry != mStreamSlot.end();
653 slotEntry++ ) {
654 size_t entries = get_camera_metadata_entry_count(*slotEntry);
655 size_t dataBytes = get_camera_metadata_data_count(*slotEntry);
656
657 camera_metadata_t *copy =
658 allocate_camera_metadata(entries, dataBytes);
659 append_camera_metadata(copy, *slotEntry);
660 mEntries.push_back(copy);
661 }
662 mCount = mStreamSlotCount;
663 }
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700664 ALOGVV("MetadataQueue: deque (%d buffers)", mCount);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700665 camera_metadata_t *b = *(mEntries.begin());
666 mEntries.erase(mEntries.begin());
667
668 if (incrementCount) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700669 ATRACE_INT("cam2_request", mFrameCount);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700670 camera_metadata_entry_t frameCount;
671 res = find_camera_metadata_entry(b,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700672 ANDROID_REQUEST_FRAME_COUNT,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700673 &frameCount);
674 if (res != OK) {
675 ALOGE("%s: Unable to add frame count: %s (%d)",
676 __FUNCTION__, strerror(-res), res);
677 } else {
678 *frameCount.data.i32 = mFrameCount;
679 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700680 mFrameCount++;
681 }
682
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700683 // Check for request ID, and if present, signal waiters.
684 camera_metadata_entry_t requestId;
685 res = find_camera_metadata_entry(b,
686 ANDROID_REQUEST_ID,
687 &requestId);
688 if (res == OK) {
689 mLatestRequestId = requestId.data.i32[0];
690 mNewRequestId.signal();
691 }
692
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700693 *buf = b;
694 mCount--;
695
696 return OK;
697}
698
699status_t Camera2Device::MetadataQueue::waitForBuffer(nsecs_t timeout)
700{
701 Mutex::Autolock l(mMutex);
702 status_t res;
703 while (mCount == 0) {
704 res = notEmpty.waitRelative(mMutex,timeout);
705 if (res != OK) return res;
706 }
707 return OK;
708}
709
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700710status_t Camera2Device::MetadataQueue::waitForDequeue(int32_t id,
711 nsecs_t timeout) {
712 Mutex::Autolock l(mMutex);
713 status_t res;
714 while (mLatestRequestId != id) {
715 nsecs_t startTime = systemTime();
716
717 res = mNewRequestId.waitRelative(mMutex, timeout);
718 if (res != OK) return res;
719
720 timeout -= (systemTime() - startTime);
721 }
722
723 return OK;
724}
725
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700726status_t Camera2Device::MetadataQueue::setStreamSlot(camera_metadata_t *buf)
727{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700728 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700729 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700730 Mutex::Autolock l(mMutex);
731 if (buf == NULL) {
732 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
733 mStreamSlotCount = 0;
734 return OK;
735 }
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700736 camera_metadata_t *buf2 = clone_camera_metadata(buf);
737 if (!buf2) {
738 ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__);
739 return NO_MEMORY;
740 }
741
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700742 if (mStreamSlotCount > 1) {
743 List<camera_metadata_t*>::iterator deleter = ++mStreamSlot.begin();
744 freeBuffers(++mStreamSlot.begin(), mStreamSlot.end());
745 mStreamSlotCount = 1;
746 }
747 if (mStreamSlotCount == 1) {
748 free_camera_metadata( *(mStreamSlot.begin()) );
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700749 *(mStreamSlot.begin()) = buf2;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700750 } else {
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700751 mStreamSlot.push_front(buf2);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700752 mStreamSlotCount = 1;
753 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700754 return signalConsumerLocked();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700755}
756
757status_t Camera2Device::MetadataQueue::setStreamSlot(
758 const List<camera_metadata_t*> &bufs)
759{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700760 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700761 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700762 Mutex::Autolock l(mMutex);
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700763
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700764 if (mStreamSlotCount > 0) {
765 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
766 }
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700767 mStreamSlotCount = 0;
768 for (List<camera_metadata_t*>::const_iterator r = bufs.begin();
769 r != bufs.end(); r++) {
770 camera_metadata_t *r2 = clone_camera_metadata(*r);
771 if (!r2) {
772 ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__);
773 return NO_MEMORY;
774 }
775 mStreamSlot.push_back(r2);
776 mStreamSlotCount++;
777 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700778 return signalConsumerLocked();
779}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700780
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -0700781status_t Camera2Device::MetadataQueue::clear()
782{
783 ATRACE_CALL();
784 ALOGV("%s: E", __FUNCTION__);
785
786 Mutex::Autolock l(mMutex);
787
788 // Clear streaming slot
789 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
790 mStreamSlotCount = 0;
791
792 // Clear request queue
793 freeBuffers(mEntries.begin(), mEntries.end());
794 mCount = 0;
795 return OK;
796}
797
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700798status_t Camera2Device::MetadataQueue::dump(int fd,
Igor Murashkinebe3f692012-10-12 16:56:11 -0700799 const Vector<String16>& /*args*/) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700800 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700801 String8 result;
802 status_t notLocked;
803 notLocked = mMutex.tryLock();
804 if (notLocked) {
805 result.append(" (Unable to lock queue mutex)\n");
806 }
807 result.appendFormat(" Current frame number: %d\n", mFrameCount);
808 if (mStreamSlotCount == 0) {
809 result.append(" Stream slot: Empty\n");
810 write(fd, result.string(), result.size());
811 } else {
Kévin PETIT377b2ec2014-02-03 12:35:36 +0000812 result.appendFormat(" Stream slot: %zu entries\n",
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700813 mStreamSlot.size());
814 int i = 0;
815 for (List<camera_metadata_t*>::iterator r = mStreamSlot.begin();
816 r != mStreamSlot.end(); r++) {
817 result = String8::format(" Stream slot buffer %d:\n", i);
818 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700819 dump_indented_camera_metadata(*r, fd, 2, 10);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700820 i++;
821 }
822 }
823 if (mEntries.size() == 0) {
824 result = " Main queue is empty\n";
825 write(fd, result.string(), result.size());
826 } else {
Kévin PETIT377b2ec2014-02-03 12:35:36 +0000827 result = String8::format(" Main queue has %zu entries:\n",
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700828 mEntries.size());
829 int i = 0;
830 for (List<camera_metadata_t*>::iterator r = mEntries.begin();
831 r != mEntries.end(); r++) {
832 result = String8::format(" Queue entry %d:\n", i);
833 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700834 dump_indented_camera_metadata(*r, fd, 2, 10);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700835 i++;
836 }
837 }
838
839 if (notLocked == 0) {
840 mMutex.unlock();
841 }
842
843 return OK;
844}
845
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700846status_t Camera2Device::MetadataQueue::signalConsumerLocked() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700847 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700848 status_t res = OK;
849 notEmpty.signal();
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800850 if (mSignalConsumer && mHal2Device != NULL) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700851 mSignalConsumer = false;
852
853 mMutex.unlock();
854 ALOGV("%s: Signaling consumer", __FUNCTION__);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800855 res = mHal2Device->ops->notify_request_queue_not_empty(mHal2Device);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700856 mMutex.lock();
857 }
858 return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700859}
860
861status_t Camera2Device::MetadataQueue::freeBuffers(
862 List<camera_metadata_t*>::iterator start,
863 List<camera_metadata_t*>::iterator end)
864{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700865 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700866 while (start != end) {
867 free_camera_metadata(*start);
868 start = mStreamSlot.erase(start);
869 }
870 return OK;
871}
872
873Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
874 const camera2_request_queue_src_ops_t *q)
875{
876 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
877 return const_cast<MetadataQueue*>(cmq);
878}
879
880Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
881 const camera2_frame_queue_dst_ops_t *q)
882{
883 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
884 return const_cast<MetadataQueue*>(cmq);
885}
886
887int Camera2Device::MetadataQueue::consumer_buffer_count(
888 const camera2_request_queue_src_ops_t *q)
889{
890 MetadataQueue *queue = getInstance(q);
891 return queue->getBufferCount();
892}
893
894int Camera2Device::MetadataQueue::consumer_dequeue(
895 const camera2_request_queue_src_ops_t *q,
896 camera_metadata_t **buffer)
897{
898 MetadataQueue *queue = getInstance(q);
899 return queue->dequeue(buffer, true);
900}
901
902int Camera2Device::MetadataQueue::consumer_free(
903 const camera2_request_queue_src_ops_t *q,
904 camera_metadata_t *old_buffer)
905{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700906 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700907 MetadataQueue *queue = getInstance(q);
Igor Murashkinebe3f692012-10-12 16:56:11 -0700908 (void)queue;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700909 free_camera_metadata(old_buffer);
910 return OK;
911}
912
913int Camera2Device::MetadataQueue::producer_dequeue(
Igor Murashkinebe3f692012-10-12 16:56:11 -0700914 const camera2_frame_queue_dst_ops_t * /*q*/,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700915 size_t entries, size_t bytes,
916 camera_metadata_t **buffer)
917{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700918 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700919 camera_metadata_t *new_buffer =
920 allocate_camera_metadata(entries, bytes);
921 if (new_buffer == NULL) return NO_MEMORY;
922 *buffer = new_buffer;
923 return OK;
924}
925
926int Camera2Device::MetadataQueue::producer_cancel(
Igor Murashkinebe3f692012-10-12 16:56:11 -0700927 const camera2_frame_queue_dst_ops_t * /*q*/,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700928 camera_metadata_t *old_buffer)
929{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700930 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700931 free_camera_metadata(old_buffer);
932 return OK;
933}
934
935int Camera2Device::MetadataQueue::producer_enqueue(
936 const camera2_frame_queue_dst_ops_t *q,
937 camera_metadata_t *filled_buffer)
938{
939 MetadataQueue *queue = getInstance(q);
940 return queue->enqueue(filled_buffer);
941}
942
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700943/**
944 * Camera2Device::StreamAdapter
945 */
946
947#ifndef container_of
948#define container_of(ptr, type, member) \
949 (type *)((char*)(ptr) - offsetof(type, member))
950#endif
951
952Camera2Device::StreamAdapter::StreamAdapter(camera2_device_t *d):
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700953 mState(RELEASED),
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800954 mHal2Device(d),
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700955 mId(-1),
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700956 mWidth(0), mHeight(0), mFormat(0), mSize(0), mUsage(0),
957 mMaxProducerBuffers(0), mMaxConsumerBuffers(0),
958 mTotalBuffers(0),
959 mFormatRequested(0),
960 mActiveBuffers(0),
961 mFrameCount(0),
962 mLastTimestamp(0)
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700963{
964 camera2_stream_ops::dequeue_buffer = dequeue_buffer;
965 camera2_stream_ops::enqueue_buffer = enqueue_buffer;
966 camera2_stream_ops::cancel_buffer = cancel_buffer;
967 camera2_stream_ops::set_crop = set_crop;
968}
969
970Camera2Device::StreamAdapter::~StreamAdapter() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700971 ATRACE_CALL();
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700972 if (mState != RELEASED) {
973 release();
974 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700975}
976
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700977status_t Camera2Device::StreamAdapter::connectToDevice(
978 sp<ANativeWindow> consumer,
979 uint32_t width, uint32_t height, int format, size_t size) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700980 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700981 status_t res;
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700982 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700983
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700984 if (mState != RELEASED) return INVALID_OPERATION;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700985 if (consumer == NULL) {
986 ALOGE("%s: Null consumer passed to stream adapter", __FUNCTION__);
987 return BAD_VALUE;
988 }
989
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700990 ALOGV("%s: New stream parameters %d x %d, format 0x%x, size %d",
991 __FUNCTION__, width, height, format, size);
992
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700993 mConsumerInterface = consumer;
994 mWidth = width;
995 mHeight = height;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700996 mSize = (format == HAL_PIXEL_FORMAT_BLOB) ? size : 0;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700997 mFormatRequested = format;
998
999 // Allocate device-side stream interface
1000
1001 uint32_t id;
1002 uint32_t formatActual;
1003 uint32_t usage;
1004 uint32_t maxBuffers = 2;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001005 res = mHal2Device->ops->allocate_stream(mHal2Device,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001006 mWidth, mHeight, mFormatRequested, getStreamOps(),
1007 &id, &formatActual, &usage, &maxBuffers);
1008 if (res != OK) {
1009 ALOGE("%s: Device stream allocation failed: %s (%d)",
1010 __FUNCTION__, strerror(-res), res);
1011 return res;
1012 }
1013
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001014 ALOGV("%s: Allocated stream id %d, actual format 0x%x, "
1015 "usage 0x%x, producer wants %d buffers", __FUNCTION__,
1016 id, formatActual, usage, maxBuffers);
1017
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001018 mId = id;
1019 mFormat = formatActual;
1020 mUsage = usage;
1021 mMaxProducerBuffers = maxBuffers;
1022
1023 mState = ALLOCATED;
1024
1025 // Configure consumer-side ANativeWindow interface
1026 res = native_window_api_connect(mConsumerInterface.get(),
1027 NATIVE_WINDOW_API_CAMERA);
1028 if (res != OK) {
1029 ALOGE("%s: Unable to connect to native window for stream %d",
1030 __FUNCTION__, mId);
1031
1032 return res;
1033 }
1034
1035 mState = CONNECTED;
1036
1037 res = native_window_set_usage(mConsumerInterface.get(), mUsage);
1038 if (res != OK) {
1039 ALOGE("%s: Unable to configure usage %08x for stream %d",
1040 __FUNCTION__, mUsage, mId);
1041 return res;
1042 }
1043
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001044 res = native_window_set_scaling_mode(mConsumerInterface.get(),
1045 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
1046 if (res != OK) {
1047 ALOGE("%s: Unable to configure stream scaling: %s (%d)",
1048 __FUNCTION__, strerror(-res), res);
1049 return res;
1050 }
1051
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001052 res = setTransform(0);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001053 if (res != OK) {
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001054 return res;
1055 }
1056
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001057 if (mFormat == HAL_PIXEL_FORMAT_BLOB) {
1058 res = native_window_set_buffers_geometry(mConsumerInterface.get(),
1059 mSize, 1, mFormat);
1060 if (res != OK) {
1061 ALOGE("%s: Unable to configure compressed stream buffer geometry"
1062 " %d x %d, size %d for stream %d",
1063 __FUNCTION__, mWidth, mHeight, mSize, mId);
1064 return res;
1065 }
1066 } else {
1067 res = native_window_set_buffers_geometry(mConsumerInterface.get(),
1068 mWidth, mHeight, mFormat);
1069 if (res != OK) {
1070 ALOGE("%s: Unable to configure stream buffer geometry"
1071 " %d x %d, format 0x%x for stream %d",
1072 __FUNCTION__, mWidth, mHeight, mFormat, mId);
1073 return res;
1074 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001075 }
1076
1077 int maxConsumerBuffers;
1078 res = mConsumerInterface->query(mConsumerInterface.get(),
1079 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &maxConsumerBuffers);
1080 if (res != OK) {
1081 ALOGE("%s: Unable to query consumer undequeued"
1082 " buffer count for stream %d", __FUNCTION__, mId);
1083 return res;
1084 }
1085 mMaxConsumerBuffers = maxConsumerBuffers;
1086
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001087 ALOGV("%s: Consumer wants %d buffers", __FUNCTION__,
1088 mMaxConsumerBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001089
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001090 mTotalBuffers = mMaxConsumerBuffers + mMaxProducerBuffers;
1091 mActiveBuffers = 0;
1092 mFrameCount = 0;
1093 mLastTimestamp = 0;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001094
1095 res = native_window_set_buffer_count(mConsumerInterface.get(),
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001096 mTotalBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001097 if (res != OK) {
1098 ALOGE("%s: Unable to set buffer count for stream %d",
1099 __FUNCTION__, mId);
1100 return res;
1101 }
1102
1103 // Register allocated buffers with HAL device
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001104 buffer_handle_t *buffers = new buffer_handle_t[mTotalBuffers];
1105 ANativeWindowBuffer **anwBuffers = new ANativeWindowBuffer*[mTotalBuffers];
1106 uint32_t bufferIdx = 0;
1107 for (; bufferIdx < mTotalBuffers; bufferIdx++) {
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001108 res = native_window_dequeue_buffer_and_wait(mConsumerInterface.get(),
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001109 &anwBuffers[bufferIdx]);
1110 if (res != OK) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001111 ALOGE("%s: Unable to dequeue buffer %d for initial registration for "
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001112 "stream %d", __FUNCTION__, bufferIdx, mId);
1113 goto cleanUpBuffers;
1114 }
1115
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001116 buffers[bufferIdx] = anwBuffers[bufferIdx]->handle;
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001117 ALOGV("%s: Buffer %p allocated", __FUNCTION__, (void*)buffers[bufferIdx]);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001118 }
1119
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001120 ALOGV("%s: Registering %d buffers with camera HAL", __FUNCTION__, mTotalBuffers);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001121 res = mHal2Device->ops->register_stream_buffers(mHal2Device,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001122 mId,
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001123 mTotalBuffers,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001124 buffers);
1125 if (res != OK) {
1126 ALOGE("%s: Unable to register buffers with HAL device for stream %d",
1127 __FUNCTION__, mId);
1128 } else {
1129 mState = ACTIVE;
1130 }
1131
1132cleanUpBuffers:
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001133 ALOGV("%s: Cleaning up %d buffers", __FUNCTION__, bufferIdx);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001134 for (uint32_t i = 0; i < bufferIdx; i++) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001135 res = mConsumerInterface->cancelBuffer(mConsumerInterface.get(),
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001136 anwBuffers[i], -1);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001137 if (res != OK) {
1138 ALOGE("%s: Unable to cancel buffer %d after registration",
1139 __FUNCTION__, i);
1140 }
1141 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001142 delete[] anwBuffers;
1143 delete[] buffers;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001144
1145 return res;
1146}
1147
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001148status_t Camera2Device::StreamAdapter::release() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001149 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001150 status_t res;
Eino-Ville Talvala02f84572013-04-23 15:16:57 -07001151 ALOGV("%s: Releasing stream %d (%d x %d, format %d)", __FUNCTION__, mId,
1152 mWidth, mHeight, mFormat);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001153 if (mState >= ALLOCATED) {
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001154 res = mHal2Device->ops->release_stream(mHal2Device, mId);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001155 if (res != OK) {
1156 ALOGE("%s: Unable to release stream %d",
1157 __FUNCTION__, mId);
1158 return res;
1159 }
1160 }
1161 if (mState >= CONNECTED) {
1162 res = native_window_api_disconnect(mConsumerInterface.get(),
1163 NATIVE_WINDOW_API_CAMERA);
Igor Murashkina1e5dcc2012-10-02 15:21:31 -07001164
1165 /* this is not an error. if client calling process dies,
1166 the window will also die and all calls to it will return
1167 DEAD_OBJECT, thus it's already "disconnected" */
1168 if (res == DEAD_OBJECT) {
1169 ALOGW("%s: While disconnecting stream %d from native window, the"
1170 " native window died from under us", __FUNCTION__, mId);
1171 }
1172 else if (res != OK) {
1173 ALOGE("%s: Unable to disconnect stream %d from native window (error %d %s)",
1174 __FUNCTION__, mId, res, strerror(-res));
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001175 return res;
1176 }
1177 }
1178 mId = -1;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001179 mState = RELEASED;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001180 return OK;
1181}
1182
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001183status_t Camera2Device::StreamAdapter::setTransform(int transform) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001184 ATRACE_CALL();
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001185 status_t res;
1186 if (mState < CONNECTED) {
1187 ALOGE("%s: Cannot set transform on unconnected stream", __FUNCTION__);
1188 return INVALID_OPERATION;
1189 }
1190 res = native_window_set_buffers_transform(mConsumerInterface.get(),
1191 transform);
1192 if (res != OK) {
1193 ALOGE("%s: Unable to configure stream transform to %x: %s (%d)",
1194 __FUNCTION__, transform, strerror(-res), res);
1195 }
1196 return res;
1197}
1198
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001199status_t Camera2Device::StreamAdapter::dump(int fd,
Igor Murashkinebe3f692012-10-12 16:56:11 -07001200 const Vector<String16>& /*args*/) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001201 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001202 String8 result = String8::format(" Stream %d: %d x %d, format 0x%x\n",
1203 mId, mWidth, mHeight, mFormat);
Kévin PETIT377b2ec2014-02-03 12:35:36 +00001204 result.appendFormat(" size %zu, usage 0x%x, requested format 0x%x\n",
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001205 mSize, mUsage, mFormatRequested);
1206 result.appendFormat(" total buffers: %d, dequeued buffers: %d\n",
1207 mTotalBuffers, mActiveBuffers);
Kévin PETIT377b2ec2014-02-03 12:35:36 +00001208 result.appendFormat(" frame count: %d, last timestamp %" PRId64 "\n",
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001209 mFrameCount, mLastTimestamp);
1210 write(fd, result.string(), result.size());
1211 return OK;
1212}
1213
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001214const camera2_stream_ops *Camera2Device::StreamAdapter::getStreamOps() {
1215 return static_cast<camera2_stream_ops *>(this);
1216}
1217
1218ANativeWindow* Camera2Device::StreamAdapter::toANW(
1219 const camera2_stream_ops_t *w) {
1220 return static_cast<const StreamAdapter*>(w)->mConsumerInterface.get();
1221}
1222
1223int Camera2Device::StreamAdapter::dequeue_buffer(const camera2_stream_ops_t *w,
1224 buffer_handle_t** buffer) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001225 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001226 int res;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001227 StreamAdapter* stream =
1228 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
1229 if (stream->mState != ACTIVE) {
1230 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001231 return INVALID_OPERATION;
1232 }
1233
1234 ANativeWindow *a = toANW(w);
1235 ANativeWindowBuffer* anb;
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001236 res = native_window_dequeue_buffer_and_wait(a, &anb);
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001237 if (res != OK) {
1238 ALOGE("Stream %d dequeue: Error from native_window: %s (%d)", stream->mId,
1239 strerror(-res), res);
1240 return res;
1241 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001242
1243 *buffer = &(anb->handle);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001244 stream->mActiveBuffers++;
1245
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001246 ALOGVV("Stream %d dequeue: Buffer %p dequeued", stream->mId, (void*)(**buffer));
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001247 return res;
1248}
1249
1250int Camera2Device::StreamAdapter::enqueue_buffer(const camera2_stream_ops_t* w,
1251 int64_t timestamp,
1252 buffer_handle_t* buffer) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001253 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001254 StreamAdapter *stream =
1255 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001256 stream->mFrameCount++;
1257 ALOGVV("Stream %d enqueue: Frame %d (%p) captured at %lld ns",
James Donga289bf62012-09-05 16:46:36 -07001258 stream->mId, stream->mFrameCount, (void*)(*buffer), timestamp);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001259 int state = stream->mState;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001260 if (state != ACTIVE) {
1261 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1262 return INVALID_OPERATION;
1263 }
1264 ANativeWindow *a = toANW(w);
1265 status_t err;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001266
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001267 err = native_window_set_buffers_timestamp(a, timestamp);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001268 if (err != OK) {
1269 ALOGE("%s: Error setting timestamp on native window: %s (%d)",
1270 __FUNCTION__, strerror(-err), err);
1271 return err;
1272 }
1273 err = a->queueBuffer(a,
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001274 container_of(buffer, ANativeWindowBuffer, handle), -1);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001275 if (err != OK) {
1276 ALOGE("%s: Error queueing buffer to native window: %s (%d)",
1277 __FUNCTION__, strerror(-err), err);
James Dong31d377b2012-08-09 17:43:46 -07001278 return err;
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001279 }
James Dong31d377b2012-08-09 17:43:46 -07001280
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001281 stream->mActiveBuffers--;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001282 stream->mLastTimestamp = timestamp;
James Dong31d377b2012-08-09 17:43:46 -07001283 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001284}
1285
1286int Camera2Device::StreamAdapter::cancel_buffer(const camera2_stream_ops_t* w,
1287 buffer_handle_t* buffer) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001288 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001289 StreamAdapter *stream =
1290 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001291 ALOGVV("Stream %d cancel: Buffer %p",
1292 stream->mId, (void*)(*buffer));
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001293 if (stream->mState != ACTIVE) {
1294 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001295 return INVALID_OPERATION;
1296 }
James Dong31d377b2012-08-09 17:43:46 -07001297
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001298 ANativeWindow *a = toANW(w);
James Dong31d377b2012-08-09 17:43:46 -07001299 int err = a->cancelBuffer(a,
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001300 container_of(buffer, ANativeWindowBuffer, handle), -1);
James Dong31d377b2012-08-09 17:43:46 -07001301 if (err != OK) {
1302 ALOGE("%s: Error canceling buffer to native window: %s (%d)",
1303 __FUNCTION__, strerror(-err), err);
1304 return err;
1305 }
1306
1307 stream->mActiveBuffers--;
1308 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001309}
1310
1311int Camera2Device::StreamAdapter::set_crop(const camera2_stream_ops_t* w,
1312 int left, int top, int right, int bottom) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001313 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001314 int state = static_cast<const StreamAdapter*>(w)->mState;
1315 if (state != ACTIVE) {
1316 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1317 return INVALID_OPERATION;
1318 }
1319 ANativeWindow *a = toANW(w);
1320 android_native_rect_t crop = { left, top, right, bottom };
1321 return native_window_set_crop(a, &crop);
1322}
1323
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001324/**
1325 * Camera2Device::ReprocessStreamAdapter
1326 */
1327
1328#ifndef container_of
1329#define container_of(ptr, type, member) \
1330 (type *)((char*)(ptr) - offsetof(type, member))
1331#endif
1332
1333Camera2Device::ReprocessStreamAdapter::ReprocessStreamAdapter(camera2_device_t *d):
1334 mState(RELEASED),
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001335 mHal2Device(d),
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001336 mId(-1),
1337 mWidth(0), mHeight(0), mFormat(0),
1338 mActiveBuffers(0),
1339 mFrameCount(0)
1340{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001341 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001342 camera2_stream_in_ops::acquire_buffer = acquire_buffer;
1343 camera2_stream_in_ops::release_buffer = release_buffer;
1344}
1345
1346Camera2Device::ReprocessStreamAdapter::~ReprocessStreamAdapter() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001347 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001348 if (mState != RELEASED) {
1349 release();
1350 }
1351}
1352
1353status_t Camera2Device::ReprocessStreamAdapter::connectToDevice(
1354 const sp<StreamAdapter> &outputStream) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001355 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001356 status_t res;
1357 ALOGV("%s: E", __FUNCTION__);
1358
1359 if (mState != RELEASED) return INVALID_OPERATION;
1360 if (outputStream == NULL) {
1361 ALOGE("%s: Null base stream passed to reprocess stream adapter",
1362 __FUNCTION__);
1363 return BAD_VALUE;
1364 }
1365
1366 mBaseStream = outputStream;
1367 mWidth = outputStream->getWidth();
1368 mHeight = outputStream->getHeight();
1369 mFormat = outputStream->getFormat();
1370
1371 ALOGV("%s: New reprocess stream parameters %d x %d, format 0x%x",
1372 __FUNCTION__, mWidth, mHeight, mFormat);
1373
1374 // Allocate device-side stream interface
1375
1376 uint32_t id;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001377 res = mHal2Device->ops->allocate_reprocess_stream_from_stream(mHal2Device,
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001378 outputStream->getId(), getStreamOps(),
1379 &id);
1380 if (res != OK) {
1381 ALOGE("%s: Device reprocess stream allocation failed: %s (%d)",
1382 __FUNCTION__, strerror(-res), res);
1383 return res;
1384 }
1385
1386 ALOGV("%s: Allocated reprocess stream id %d based on stream %d",
1387 __FUNCTION__, id, outputStream->getId());
1388
1389 mId = id;
1390
1391 mState = ACTIVE;
1392
1393 return OK;
1394}
1395
1396status_t Camera2Device::ReprocessStreamAdapter::release() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001397 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001398 status_t res;
1399 ALOGV("%s: Releasing stream %d", __FUNCTION__, mId);
1400 if (mState >= ACTIVE) {
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001401 res = mHal2Device->ops->release_reprocess_stream(mHal2Device, mId);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001402 if (res != OK) {
1403 ALOGE("%s: Unable to release stream %d",
1404 __FUNCTION__, mId);
1405 return res;
1406 }
1407 }
1408
1409 List<QueueEntry>::iterator s;
1410 for (s = mQueue.begin(); s != mQueue.end(); s++) {
1411 sp<BufferReleasedListener> listener = s->releaseListener.promote();
1412 if (listener != 0) listener->onBufferReleased(s->handle);
1413 }
1414 for (s = mInFlightQueue.begin(); s != mInFlightQueue.end(); s++) {
1415 sp<BufferReleasedListener> listener = s->releaseListener.promote();
1416 if (listener != 0) listener->onBufferReleased(s->handle);
1417 }
1418 mQueue.clear();
1419 mInFlightQueue.clear();
1420
1421 mState = RELEASED;
1422 return OK;
1423}
1424
1425status_t Camera2Device::ReprocessStreamAdapter::pushIntoStream(
1426 buffer_handle_t *handle, const wp<BufferReleasedListener> &releaseListener) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001427 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001428 // TODO: Some error checking here would be nice
1429 ALOGV("%s: Pushing buffer %p to stream", __FUNCTION__, (void*)(*handle));
1430
1431 QueueEntry entry;
1432 entry.handle = handle;
1433 entry.releaseListener = releaseListener;
1434 mQueue.push_back(entry);
1435 return OK;
1436}
1437
1438status_t Camera2Device::ReprocessStreamAdapter::dump(int fd,
Igor Murashkinebe3f692012-10-12 16:56:11 -07001439 const Vector<String16>& /*args*/) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001440 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001441 String8 result =
1442 String8::format(" Reprocess stream %d: %d x %d, fmt 0x%x\n",
1443 mId, mWidth, mHeight, mFormat);
1444 result.appendFormat(" acquired buffers: %d\n",
1445 mActiveBuffers);
1446 result.appendFormat(" frame count: %d\n",
1447 mFrameCount);
1448 write(fd, result.string(), result.size());
1449 return OK;
1450}
1451
1452const camera2_stream_in_ops *Camera2Device::ReprocessStreamAdapter::getStreamOps() {
1453 return static_cast<camera2_stream_in_ops *>(this);
1454}
1455
1456int Camera2Device::ReprocessStreamAdapter::acquire_buffer(
1457 const camera2_stream_in_ops_t *w,
1458 buffer_handle_t** buffer) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001459 ATRACE_CALL();
Igor Murashkinebe3f692012-10-12 16:56:11 -07001460
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001461 ReprocessStreamAdapter* stream =
1462 const_cast<ReprocessStreamAdapter*>(
1463 static_cast<const ReprocessStreamAdapter*>(w));
1464 if (stream->mState != ACTIVE) {
1465 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
1466 return INVALID_OPERATION;
1467 }
1468
1469 if (stream->mQueue.empty()) {
1470 *buffer = NULL;
1471 return OK;
1472 }
1473
1474 QueueEntry &entry = *(stream->mQueue.begin());
1475
1476 *buffer = entry.handle;
1477
1478 stream->mInFlightQueue.push_back(entry);
1479 stream->mQueue.erase(stream->mQueue.begin());
1480
1481 stream->mActiveBuffers++;
1482
1483 ALOGV("Stream %d acquire: Buffer %p acquired", stream->mId,
1484 (void*)(**buffer));
1485 return OK;
1486}
1487
1488int Camera2Device::ReprocessStreamAdapter::release_buffer(
1489 const camera2_stream_in_ops_t* w,
1490 buffer_handle_t* buffer) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001491 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001492 ReprocessStreamAdapter *stream =
1493 const_cast<ReprocessStreamAdapter*>(
1494 static_cast<const ReprocessStreamAdapter*>(w) );
1495 stream->mFrameCount++;
1496 ALOGV("Reprocess stream %d release: Frame %d (%p)",
1497 stream->mId, stream->mFrameCount, (void*)*buffer);
1498 int state = stream->mState;
1499 if (state != ACTIVE) {
1500 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1501 return INVALID_OPERATION;
1502 }
1503 stream->mActiveBuffers--;
1504
1505 List<QueueEntry>::iterator s;
1506 for (s = stream->mInFlightQueue.begin(); s != stream->mInFlightQueue.end(); s++) {
1507 if ( s->handle == buffer ) break;
1508 }
1509 if (s == stream->mInFlightQueue.end()) {
1510 ALOGE("%s: Can't find buffer %p in in-flight list!", __FUNCTION__,
1511 buffer);
1512 return INVALID_OPERATION;
1513 }
1514
1515 sp<BufferReleasedListener> listener = s->releaseListener.promote();
1516 if (listener != 0) {
1517 listener->onBufferReleased(s->handle);
1518 } else {
1519 ALOGE("%s: Can't free buffer - missing listener", __FUNCTION__);
1520 }
1521 stream->mInFlightQueue.erase(s);
1522
1523 return OK;
1524}
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001525
1526}; // namespace android