blob: c33c166144726250ab8c56434641c064bf2e8f31 [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
Jianing Weicb0652e2014-03-12 18:29:36 -0700202status_t Camera2Device::capture(CameraMetadata &request, int64_t* /*lastFrameNumber*/) {
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 Weicb0652e2014-03-12 18:29:36 -0700210status_t Camera2Device::captureList(const List<const CameraMetadata> &requests,
211 int64_t* /*lastFrameNumber*/) {
Jianing Wei90e59c92014-03-12 18:29:36 -0700212 ATRACE_CALL();
213 ALOGE("%s: Camera2Device burst capture not implemented", __FUNCTION__);
214 return INVALID_OPERATION;
215}
216
Jianing Weicb0652e2014-03-12 18:29:36 -0700217status_t Camera2Device::setStreamingRequest(const CameraMetadata &request,
218 int64_t* /*lastFrameNumber*/) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700219 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700220 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700221 CameraMetadata streamRequest(request);
222 return mRequestQueue.setStreamSlot(streamRequest.release());
223}
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700224
Jianing Weicb0652e2014-03-12 18:29:36 -0700225status_t Camera2Device::setStreamingRequestList(const List<const CameraMetadata> &requests,
226 int64_t* /*lastFrameNumber*/) {
Jianing Wei90e59c92014-03-12 18:29:36 -0700227 ATRACE_CALL();
228 ALOGE("%s, Camera2Device streaming burst not implemented", __FUNCTION__);
229 return INVALID_OPERATION;
230}
231
Jianing Weicb0652e2014-03-12 18:29:36 -0700232status_t Camera2Device::clearStreamingRequest(int64_t* /*lastFrameNumber*/) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700233 ATRACE_CALL();
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700234 return mRequestQueue.setStreamSlot(NULL);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700235}
236
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700237status_t Camera2Device::waitUntilRequestReceived(int32_t requestId, nsecs_t timeout) {
238 ATRACE_CALL();
239 return mRequestQueue.waitForDequeue(requestId, timeout);
240}
241
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700242status_t Camera2Device::createStream(sp<ANativeWindow> consumer,
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700243 uint32_t width, uint32_t height, int format, size_t size, int *id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700244 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700245 status_t res;
246 ALOGV("%s: E", __FUNCTION__);
247
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800248 sp<StreamAdapter> stream = new StreamAdapter(mHal2Device);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700249
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700250 res = stream->connectToDevice(consumer, width, height, format, size);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700251 if (res != OK) {
252 ALOGE("%s: Camera %d: Unable to create stream (%d x %d, format %x):"
253 "%s (%d)",
254 __FUNCTION__, mId, width, height, format, strerror(-res), res);
255 return res;
256 }
257
258 *id = stream->getId();
259
260 mStreams.push_back(stream);
261 return OK;
262}
263
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700264status_t Camera2Device::createReprocessStreamFromStream(int outputId, int *id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700265 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700266 status_t res;
267 ALOGV("%s: E", __FUNCTION__);
268
269 bool found = false;
270 StreamList::iterator streamI;
271 for (streamI = mStreams.begin();
272 streamI != mStreams.end(); streamI++) {
273 if ((*streamI)->getId() == outputId) {
274 found = true;
275 break;
276 }
277 }
278 if (!found) {
279 ALOGE("%s: Camera %d: Output stream %d doesn't exist; can't create "
280 "reprocess stream from it!", __FUNCTION__, mId, outputId);
281 return BAD_VALUE;
282 }
283
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800284 sp<ReprocessStreamAdapter> stream = new ReprocessStreamAdapter(mHal2Device);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700285
286 res = stream->connectToDevice((*streamI));
287 if (res != OK) {
288 ALOGE("%s: Camera %d: Unable to create reprocessing stream from "\
289 "stream %d: %s (%d)", __FUNCTION__, mId, outputId,
290 strerror(-res), res);
291 return res;
292 }
293
294 *id = stream->getId();
295
296 mReprocessStreams.push_back(stream);
297 return OK;
298}
299
300
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700301status_t Camera2Device::getStreamInfo(int id,
302 uint32_t *width, uint32_t *height, uint32_t *format) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700303 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700304 ALOGV("%s: E", __FUNCTION__);
305 bool found = false;
306 StreamList::iterator streamI;
307 for (streamI = mStreams.begin();
308 streamI != mStreams.end(); streamI++) {
309 if ((*streamI)->getId() == id) {
310 found = true;
311 break;
312 }
313 }
314 if (!found) {
315 ALOGE("%s: Camera %d: Stream %d does not exist",
316 __FUNCTION__, mId, id);
317 return BAD_VALUE;
318 }
319
320 if (width) *width = (*streamI)->getWidth();
321 if (height) *height = (*streamI)->getHeight();
322 if (format) *format = (*streamI)->getFormat();
323
324 return OK;
325}
326
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -0700327status_t Camera2Device::setStreamTransform(int id,
328 int transform) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700329 ATRACE_CALL();
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -0700330 ALOGV("%s: E", __FUNCTION__);
331 bool found = false;
332 StreamList::iterator streamI;
333 for (streamI = mStreams.begin();
334 streamI != mStreams.end(); streamI++) {
335 if ((*streamI)->getId() == id) {
336 found = true;
337 break;
338 }
339 }
340 if (!found) {
341 ALOGE("%s: Camera %d: Stream %d does not exist",
342 __FUNCTION__, mId, id);
343 return BAD_VALUE;
344 }
345
346 return (*streamI)->setTransform(transform);
347}
348
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700349status_t Camera2Device::deleteStream(int id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700350 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700351 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700352 bool found = false;
353 for (StreamList::iterator streamI = mStreams.begin();
354 streamI != mStreams.end(); streamI++) {
355 if ((*streamI)->getId() == id) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700356 status_t res = (*streamI)->release();
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700357 if (res != OK) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700358 ALOGE("%s: Unable to release stream %d from HAL device: "
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700359 "%s (%d)", __FUNCTION__, id, strerror(-res), res);
360 return res;
361 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700362 mStreams.erase(streamI);
363 found = true;
364 break;
365 }
366 }
367 if (!found) {
368 ALOGE("%s: Camera %d: Unable to find stream %d to delete",
369 __FUNCTION__, mId, id);
370 return BAD_VALUE;
371 }
372 return OK;
373}
374
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700375status_t Camera2Device::deleteReprocessStream(int id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700376 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700377 ALOGV("%s: E", __FUNCTION__);
378 bool found = false;
379 for (ReprocessStreamList::iterator streamI = mReprocessStreams.begin();
380 streamI != mReprocessStreams.end(); streamI++) {
381 if ((*streamI)->getId() == id) {
382 status_t res = (*streamI)->release();
383 if (res != OK) {
384 ALOGE("%s: Unable to release reprocess stream %d from "
385 "HAL device: %s (%d)", __FUNCTION__, id,
386 strerror(-res), res);
387 return res;
388 }
389 mReprocessStreams.erase(streamI);
390 found = true;
391 break;
392 }
393 }
394 if (!found) {
395 ALOGE("%s: Camera %d: Unable to find stream %d to delete",
396 __FUNCTION__, mId, id);
397 return BAD_VALUE;
398 }
399 return OK;
400}
401
402
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700403status_t Camera2Device::createDefaultRequest(int templateId,
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700404 CameraMetadata *request) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700405 ATRACE_CALL();
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700406 status_t err;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700407 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700408 camera_metadata_t *rawRequest;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800409 err = mHal2Device->ops->construct_default_request(
410 mHal2Device, templateId, &rawRequest);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700411 request->acquire(rawRequest);
412 return err;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700413}
414
415status_t Camera2Device::waitUntilDrained() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700416 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700417 static const uint32_t kSleepTime = 50000; // 50 ms
418 static const uint32_t kMaxSleepTime = 10000000; // 10 s
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700419 ALOGV("%s: Camera %d: Starting wait", __FUNCTION__, mId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700420 if (mRequestQueue.getBufferCount() ==
421 CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS) return INVALID_OPERATION;
422
423 // TODO: Set up notifications from HAL, instead of sleeping here
424 uint32_t totalTime = 0;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800425 while (mHal2Device->ops->get_in_progress_count(mHal2Device) > 0) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700426 usleep(kSleepTime);
427 totalTime += kSleepTime;
428 if (totalTime > kMaxSleepTime) {
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700429 ALOGE("%s: Waited %d us, %d requests still in flight", __FUNCTION__,
Alex Rayf0eeb532013-03-17 03:23:18 -0700430 totalTime, mHal2Device->ops->get_in_progress_count(mHal2Device));
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700431 return TIMED_OUT;
432 }
433 }
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700434 ALOGV("%s: Camera %d: HAL is idle", __FUNCTION__, mId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700435 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700436}
437
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700438status_t Camera2Device::setNotifyCallback(NotificationListener *listener) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700439 ATRACE_CALL();
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700440 status_t res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800441 res = mHal2Device->ops->set_notify_callback(mHal2Device, notificationCallback,
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700442 reinterpret_cast<void*>(listener) );
443 if (res != OK) {
444 ALOGE("%s: Unable to set notification callback!", __FUNCTION__);
445 }
446 return res;
447}
448
Eino-Ville Talvala46910bd2013-07-18 19:15:17 -0700449bool Camera2Device::willNotify3A() {
450 return true;
451}
452
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700453void Camera2Device::notificationCallback(int32_t msg_type,
454 int32_t ext1,
455 int32_t ext2,
456 int32_t ext3,
457 void *user) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700458 ATRACE_CALL();
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700459 NotificationListener *listener = reinterpret_cast<NotificationListener*>(user);
460 ALOGV("%s: Notification %d, arguments %d, %d, %d", __FUNCTION__, msg_type,
461 ext1, ext2, ext3);
462 if (listener != NULL) {
463 switch (msg_type) {
464 case CAMERA2_MSG_ERROR:
Jianing Weicb0652e2014-03-12 18:29:36 -0700465 // TODO: This needs to be fixed. ext2 and ext3 need to be considered.
466 listener->notifyError(
467 ((ext1 == CAMERA2_MSG_ERROR_DEVICE)
468 || (ext1 == CAMERA2_MSG_ERROR_HARDWARE)) ?
469 ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE :
470 ICameraDeviceCallbacks::ERROR_CAMERA_SERVICE,
471 CaptureResultExtras());
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700472 break;
473 case CAMERA2_MSG_SHUTTER: {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700474 // TODO: Only needed for camera2 API, which is unsupported
475 // by HAL2 directly.
476 // nsecs_t timestamp = (nsecs_t)ext2 | ((nsecs_t)(ext3) << 32 );
477 // listener->notifyShutter(requestId, timestamp);
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700478 break;
479 }
480 case CAMERA2_MSG_AUTOFOCUS:
481 listener->notifyAutoFocus(ext1, ext2);
482 break;
483 case CAMERA2_MSG_AUTOEXPOSURE:
484 listener->notifyAutoExposure(ext1, ext2);
485 break;
486 case CAMERA2_MSG_AUTOWB:
487 listener->notifyAutoWhitebalance(ext1, ext2);
488 break;
489 default:
490 ALOGE("%s: Unknown notification %d (arguments %d, %d, %d)!",
491 __FUNCTION__, msg_type, ext1, ext2, ext3);
492 }
493 }
494}
495
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -0700496status_t Camera2Device::waitForNextFrame(nsecs_t timeout) {
497 return mFrameQueue.waitForBuffer(timeout);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700498}
499
Jianing Weicb0652e2014-03-12 18:29:36 -0700500status_t Camera2Device::getNextResult(CaptureResult *result) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700501 ATRACE_CALL();
Jianing Weicb0652e2014-03-12 18:29:36 -0700502 ALOGV("%s: get CaptureResult", __FUNCTION__);
503 if (result == NULL) {
504 ALOGE("%s: result pointer is NULL", __FUNCTION__);
505 return BAD_VALUE;
506 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700507 status_t res;
508 camera_metadata_t *rawFrame;
509 res = mFrameQueue.dequeue(&rawFrame);
Jianing Weicb0652e2014-03-12 18:29:36 -0700510 if (rawFrame == NULL) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700511 return NOT_ENOUGH_DATA;
512 } else if (res == OK) {
Jianing Weicb0652e2014-03-12 18:29:36 -0700513 result->mMetadata.acquire(rawFrame);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700514 }
Jianing Weicb0652e2014-03-12 18:29:36 -0700515
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700516 return res;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700517}
518
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700519status_t Camera2Device::triggerAutofocus(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 autofocus, 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_AUTOFOCUS, id, 0);
525 if (res != OK) {
526 ALOGE("%s: Error triggering autofocus (id %d)",
527 __FUNCTION__, id);
528 }
529 return res;
530}
531
532status_t Camera2Device::triggerCancelAutofocus(uint32_t id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700533 ATRACE_CALL();
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700534 status_t res;
535 ALOGV("%s: Canceling autofocus, id %d", __FUNCTION__, id);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800536 res = mHal2Device->ops->trigger_action(mHal2Device,
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700537 CAMERA2_TRIGGER_CANCEL_AUTOFOCUS, id, 0);
538 if (res != OK) {
539 ALOGE("%s: Error canceling autofocus (id %d)",
540 __FUNCTION__, id);
541 }
542 return res;
543}
544
545status_t Camera2Device::triggerPrecaptureMetering(uint32_t id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700546 ATRACE_CALL();
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700547 status_t res;
548 ALOGV("%s: Triggering precapture metering, id %d", __FUNCTION__, id);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800549 res = mHal2Device->ops->trigger_action(mHal2Device,
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700550 CAMERA2_TRIGGER_PRECAPTURE_METERING, id, 0);
551 if (res != OK) {
552 ALOGE("%s: Error triggering precapture metering (id %d)",
553 __FUNCTION__, id);
554 }
555 return res;
556}
557
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700558status_t Camera2Device::pushReprocessBuffer(int reprocessStreamId,
559 buffer_handle_t *buffer, wp<BufferReleasedListener> listener) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700560 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700561 ALOGV("%s: E", __FUNCTION__);
562 bool found = false;
563 status_t res = OK;
564 for (ReprocessStreamList::iterator streamI = mReprocessStreams.begin();
565 streamI != mReprocessStreams.end(); streamI++) {
566 if ((*streamI)->getId() == reprocessStreamId) {
567 res = (*streamI)->pushIntoStream(buffer, listener);
568 if (res != OK) {
569 ALOGE("%s: Unable to push buffer to reprocess stream %d: %s (%d)",
570 __FUNCTION__, reprocessStreamId, strerror(-res), res);
571 return res;
572 }
573 found = true;
574 break;
575 }
576 }
577 if (!found) {
578 ALOGE("%s: Camera %d: Unable to find reprocess stream %d",
579 __FUNCTION__, mId, reprocessStreamId);
580 res = BAD_VALUE;
581 }
582 return res;
583}
584
Jianing Weicb0652e2014-03-12 18:29:36 -0700585status_t Camera2Device::flush(int64_t* /*lastFrameNumber*/) {
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -0700586 ATRACE_CALL();
587
588 mRequestQueue.clear();
589 return waitUntilDrained();
590}
591
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700592/**
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700593 * Camera2Device::MetadataQueue
594 */
595
596Camera2Device::MetadataQueue::MetadataQueue():
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800597 mHal2Device(NULL),
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700598 mFrameCount(0),
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700599 mLatestRequestId(0),
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700600 mCount(0),
601 mStreamSlotCount(0),
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -0700602 mSignalConsumer(true)
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700603{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700604 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700605 camera2_request_queue_src_ops::dequeue_request = consumer_dequeue;
606 camera2_request_queue_src_ops::request_count = consumer_buffer_count;
607 camera2_request_queue_src_ops::free_request = consumer_free;
608
609 camera2_frame_queue_dst_ops::dequeue_frame = producer_dequeue;
610 camera2_frame_queue_dst_ops::cancel_frame = producer_cancel;
611 camera2_frame_queue_dst_ops::enqueue_frame = producer_enqueue;
612}
613
614Camera2Device::MetadataQueue::~MetadataQueue() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700615 ATRACE_CALL();
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -0700616 clear();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700617}
618
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700619// Connect to camera2 HAL as consumer (input requests/reprocessing)
620status_t Camera2Device::MetadataQueue::setConsumerDevice(camera2_device_t *d) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700621 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700622 status_t res;
623 res = d->ops->set_request_queue_src_ops(d,
624 this);
625 if (res != OK) return res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800626 mHal2Device = d;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700627 return OK;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700628}
629
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700630status_t Camera2Device::MetadataQueue::setProducerDevice(camera2_device_t *d) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700631 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700632 status_t res;
633 res = d->ops->set_frame_queue_dst_ops(d,
634 this);
635 return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700636}
637
638// Real interfaces
639status_t Camera2Device::MetadataQueue::enqueue(camera_metadata_t *buf) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700640 ATRACE_CALL();
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700641 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700642 Mutex::Autolock l(mMutex);
643
644 mCount++;
645 mEntries.push_back(buf);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700646
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700647 return signalConsumerLocked();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700648}
649
650int Camera2Device::MetadataQueue::getBufferCount() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700651 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700652 Mutex::Autolock l(mMutex);
653 if (mStreamSlotCount > 0) {
654 return CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS;
655 }
656 return mCount;
657}
658
659status_t Camera2Device::MetadataQueue::dequeue(camera_metadata_t **buf,
660 bool incrementCount)
661{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700662 ATRACE_CALL();
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700663 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700664 status_t res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700665 Mutex::Autolock l(mMutex);
666
667 if (mCount == 0) {
668 if (mStreamSlotCount == 0) {
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700669 ALOGVV("%s: Empty", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700670 *buf = NULL;
671 mSignalConsumer = true;
672 return OK;
673 }
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700674 ALOGVV("%s: Streaming %d frames to queue", __FUNCTION__,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700675 mStreamSlotCount);
676
677 for (List<camera_metadata_t*>::iterator slotEntry = mStreamSlot.begin();
678 slotEntry != mStreamSlot.end();
679 slotEntry++ ) {
680 size_t entries = get_camera_metadata_entry_count(*slotEntry);
681 size_t dataBytes = get_camera_metadata_data_count(*slotEntry);
682
683 camera_metadata_t *copy =
684 allocate_camera_metadata(entries, dataBytes);
685 append_camera_metadata(copy, *slotEntry);
686 mEntries.push_back(copy);
687 }
688 mCount = mStreamSlotCount;
689 }
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700690 ALOGVV("MetadataQueue: deque (%d buffers)", mCount);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700691 camera_metadata_t *b = *(mEntries.begin());
692 mEntries.erase(mEntries.begin());
693
694 if (incrementCount) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700695 ATRACE_INT("cam2_request", mFrameCount);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700696 camera_metadata_entry_t frameCount;
697 res = find_camera_metadata_entry(b,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700698 ANDROID_REQUEST_FRAME_COUNT,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700699 &frameCount);
700 if (res != OK) {
701 ALOGE("%s: Unable to add frame count: %s (%d)",
702 __FUNCTION__, strerror(-res), res);
703 } else {
704 *frameCount.data.i32 = mFrameCount;
705 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700706 mFrameCount++;
707 }
708
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700709 // Check for request ID, and if present, signal waiters.
710 camera_metadata_entry_t requestId;
711 res = find_camera_metadata_entry(b,
712 ANDROID_REQUEST_ID,
713 &requestId);
714 if (res == OK) {
715 mLatestRequestId = requestId.data.i32[0];
716 mNewRequestId.signal();
717 }
718
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700719 *buf = b;
720 mCount--;
721
722 return OK;
723}
724
725status_t Camera2Device::MetadataQueue::waitForBuffer(nsecs_t timeout)
726{
727 Mutex::Autolock l(mMutex);
728 status_t res;
729 while (mCount == 0) {
730 res = notEmpty.waitRelative(mMutex,timeout);
731 if (res != OK) return res;
732 }
733 return OK;
734}
735
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700736status_t Camera2Device::MetadataQueue::waitForDequeue(int32_t id,
737 nsecs_t timeout) {
738 Mutex::Autolock l(mMutex);
739 status_t res;
740 while (mLatestRequestId != id) {
741 nsecs_t startTime = systemTime();
742
743 res = mNewRequestId.waitRelative(mMutex, timeout);
744 if (res != OK) return res;
745
746 timeout -= (systemTime() - startTime);
747 }
748
749 return OK;
750}
751
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700752status_t Camera2Device::MetadataQueue::setStreamSlot(camera_metadata_t *buf)
753{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700754 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700755 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700756 Mutex::Autolock l(mMutex);
757 if (buf == NULL) {
758 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
759 mStreamSlotCount = 0;
760 return OK;
761 }
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700762 camera_metadata_t *buf2 = clone_camera_metadata(buf);
763 if (!buf2) {
764 ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__);
765 return NO_MEMORY;
766 }
767
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700768 if (mStreamSlotCount > 1) {
769 List<camera_metadata_t*>::iterator deleter = ++mStreamSlot.begin();
770 freeBuffers(++mStreamSlot.begin(), mStreamSlot.end());
771 mStreamSlotCount = 1;
772 }
773 if (mStreamSlotCount == 1) {
774 free_camera_metadata( *(mStreamSlot.begin()) );
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700775 *(mStreamSlot.begin()) = buf2;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700776 } else {
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700777 mStreamSlot.push_front(buf2);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700778 mStreamSlotCount = 1;
779 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700780 return signalConsumerLocked();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700781}
782
783status_t Camera2Device::MetadataQueue::setStreamSlot(
784 const List<camera_metadata_t*> &bufs)
785{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700786 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700787 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700788 Mutex::Autolock l(mMutex);
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700789
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700790 if (mStreamSlotCount > 0) {
791 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
792 }
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700793 mStreamSlotCount = 0;
794 for (List<camera_metadata_t*>::const_iterator r = bufs.begin();
795 r != bufs.end(); r++) {
796 camera_metadata_t *r2 = clone_camera_metadata(*r);
797 if (!r2) {
798 ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__);
799 return NO_MEMORY;
800 }
801 mStreamSlot.push_back(r2);
802 mStreamSlotCount++;
803 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700804 return signalConsumerLocked();
805}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700806
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -0700807status_t Camera2Device::MetadataQueue::clear()
808{
809 ATRACE_CALL();
810 ALOGV("%s: E", __FUNCTION__);
811
812 Mutex::Autolock l(mMutex);
813
814 // Clear streaming slot
815 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
816 mStreamSlotCount = 0;
817
818 // Clear request queue
819 freeBuffers(mEntries.begin(), mEntries.end());
820 mCount = 0;
821 return OK;
822}
823
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700824status_t Camera2Device::MetadataQueue::dump(int fd,
Igor Murashkinebe3f692012-10-12 16:56:11 -0700825 const Vector<String16>& /*args*/) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700826 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700827 String8 result;
828 status_t notLocked;
829 notLocked = mMutex.tryLock();
830 if (notLocked) {
831 result.append(" (Unable to lock queue mutex)\n");
832 }
833 result.appendFormat(" Current frame number: %d\n", mFrameCount);
834 if (mStreamSlotCount == 0) {
835 result.append(" Stream slot: Empty\n");
836 write(fd, result.string(), result.size());
837 } else {
Kévin PETIT377b2ec2014-02-03 12:35:36 +0000838 result.appendFormat(" Stream slot: %zu entries\n",
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700839 mStreamSlot.size());
840 int i = 0;
841 for (List<camera_metadata_t*>::iterator r = mStreamSlot.begin();
842 r != mStreamSlot.end(); r++) {
843 result = String8::format(" Stream slot buffer %d:\n", i);
844 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700845 dump_indented_camera_metadata(*r, fd, 2, 10);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700846 i++;
847 }
848 }
849 if (mEntries.size() == 0) {
850 result = " Main queue is empty\n";
851 write(fd, result.string(), result.size());
852 } else {
Kévin PETIT377b2ec2014-02-03 12:35:36 +0000853 result = String8::format(" Main queue has %zu entries:\n",
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700854 mEntries.size());
855 int i = 0;
856 for (List<camera_metadata_t*>::iterator r = mEntries.begin();
857 r != mEntries.end(); r++) {
858 result = String8::format(" Queue entry %d:\n", i);
859 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700860 dump_indented_camera_metadata(*r, fd, 2, 10);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700861 i++;
862 }
863 }
864
865 if (notLocked == 0) {
866 mMutex.unlock();
867 }
868
869 return OK;
870}
871
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700872status_t Camera2Device::MetadataQueue::signalConsumerLocked() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700873 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700874 status_t res = OK;
875 notEmpty.signal();
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800876 if (mSignalConsumer && mHal2Device != NULL) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700877 mSignalConsumer = false;
878
879 mMutex.unlock();
880 ALOGV("%s: Signaling consumer", __FUNCTION__);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800881 res = mHal2Device->ops->notify_request_queue_not_empty(mHal2Device);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700882 mMutex.lock();
883 }
884 return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700885}
886
887status_t Camera2Device::MetadataQueue::freeBuffers(
888 List<camera_metadata_t*>::iterator start,
889 List<camera_metadata_t*>::iterator end)
890{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700891 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700892 while (start != end) {
893 free_camera_metadata(*start);
894 start = mStreamSlot.erase(start);
895 }
896 return OK;
897}
898
899Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
900 const camera2_request_queue_src_ops_t *q)
901{
902 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
903 return const_cast<MetadataQueue*>(cmq);
904}
905
906Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
907 const camera2_frame_queue_dst_ops_t *q)
908{
909 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
910 return const_cast<MetadataQueue*>(cmq);
911}
912
913int Camera2Device::MetadataQueue::consumer_buffer_count(
914 const camera2_request_queue_src_ops_t *q)
915{
916 MetadataQueue *queue = getInstance(q);
917 return queue->getBufferCount();
918}
919
920int Camera2Device::MetadataQueue::consumer_dequeue(
921 const camera2_request_queue_src_ops_t *q,
922 camera_metadata_t **buffer)
923{
924 MetadataQueue *queue = getInstance(q);
925 return queue->dequeue(buffer, true);
926}
927
928int Camera2Device::MetadataQueue::consumer_free(
929 const camera2_request_queue_src_ops_t *q,
930 camera_metadata_t *old_buffer)
931{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700932 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700933 MetadataQueue *queue = getInstance(q);
Igor Murashkinebe3f692012-10-12 16:56:11 -0700934 (void)queue;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700935 free_camera_metadata(old_buffer);
936 return OK;
937}
938
939int Camera2Device::MetadataQueue::producer_dequeue(
Igor Murashkinebe3f692012-10-12 16:56:11 -0700940 const camera2_frame_queue_dst_ops_t * /*q*/,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700941 size_t entries, size_t bytes,
942 camera_metadata_t **buffer)
943{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700944 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700945 camera_metadata_t *new_buffer =
946 allocate_camera_metadata(entries, bytes);
947 if (new_buffer == NULL) return NO_MEMORY;
948 *buffer = new_buffer;
949 return OK;
950}
951
952int Camera2Device::MetadataQueue::producer_cancel(
Igor Murashkinebe3f692012-10-12 16:56:11 -0700953 const camera2_frame_queue_dst_ops_t * /*q*/,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700954 camera_metadata_t *old_buffer)
955{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700956 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700957 free_camera_metadata(old_buffer);
958 return OK;
959}
960
961int Camera2Device::MetadataQueue::producer_enqueue(
962 const camera2_frame_queue_dst_ops_t *q,
963 camera_metadata_t *filled_buffer)
964{
965 MetadataQueue *queue = getInstance(q);
966 return queue->enqueue(filled_buffer);
967}
968
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700969/**
970 * Camera2Device::StreamAdapter
971 */
972
973#ifndef container_of
974#define container_of(ptr, type, member) \
975 (type *)((char*)(ptr) - offsetof(type, member))
976#endif
977
978Camera2Device::StreamAdapter::StreamAdapter(camera2_device_t *d):
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700979 mState(RELEASED),
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800980 mHal2Device(d),
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700981 mId(-1),
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700982 mWidth(0), mHeight(0), mFormat(0), mSize(0), mUsage(0),
983 mMaxProducerBuffers(0), mMaxConsumerBuffers(0),
984 mTotalBuffers(0),
985 mFormatRequested(0),
986 mActiveBuffers(0),
987 mFrameCount(0),
988 mLastTimestamp(0)
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700989{
990 camera2_stream_ops::dequeue_buffer = dequeue_buffer;
991 camera2_stream_ops::enqueue_buffer = enqueue_buffer;
992 camera2_stream_ops::cancel_buffer = cancel_buffer;
993 camera2_stream_ops::set_crop = set_crop;
994}
995
996Camera2Device::StreamAdapter::~StreamAdapter() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700997 ATRACE_CALL();
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700998 if (mState != RELEASED) {
999 release();
1000 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001001}
1002
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001003status_t Camera2Device::StreamAdapter::connectToDevice(
1004 sp<ANativeWindow> consumer,
1005 uint32_t width, uint32_t height, int format, size_t size) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001006 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001007 status_t res;
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -07001008 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001009
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001010 if (mState != RELEASED) return INVALID_OPERATION;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001011 if (consumer == NULL) {
1012 ALOGE("%s: Null consumer passed to stream adapter", __FUNCTION__);
1013 return BAD_VALUE;
1014 }
1015
Colin Crosse5729fa2014-03-21 15:04:25 -07001016 ALOGV("%s: New stream parameters %d x %d, format 0x%x, size %zu",
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001017 __FUNCTION__, width, height, format, size);
1018
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001019 mConsumerInterface = consumer;
1020 mWidth = width;
1021 mHeight = height;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001022 mSize = (format == HAL_PIXEL_FORMAT_BLOB) ? size : 0;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001023 mFormatRequested = format;
1024
1025 // Allocate device-side stream interface
1026
1027 uint32_t id;
1028 uint32_t formatActual;
1029 uint32_t usage;
1030 uint32_t maxBuffers = 2;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001031 res = mHal2Device->ops->allocate_stream(mHal2Device,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001032 mWidth, mHeight, mFormatRequested, getStreamOps(),
1033 &id, &formatActual, &usage, &maxBuffers);
1034 if (res != OK) {
1035 ALOGE("%s: Device stream allocation failed: %s (%d)",
1036 __FUNCTION__, strerror(-res), res);
1037 return res;
1038 }
1039
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001040 ALOGV("%s: Allocated stream id %d, actual format 0x%x, "
1041 "usage 0x%x, producer wants %d buffers", __FUNCTION__,
1042 id, formatActual, usage, maxBuffers);
1043
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001044 mId = id;
1045 mFormat = formatActual;
1046 mUsage = usage;
1047 mMaxProducerBuffers = maxBuffers;
1048
1049 mState = ALLOCATED;
1050
1051 // Configure consumer-side ANativeWindow interface
1052 res = native_window_api_connect(mConsumerInterface.get(),
1053 NATIVE_WINDOW_API_CAMERA);
1054 if (res != OK) {
1055 ALOGE("%s: Unable to connect to native window for stream %d",
1056 __FUNCTION__, mId);
1057
1058 return res;
1059 }
1060
1061 mState = CONNECTED;
1062
1063 res = native_window_set_usage(mConsumerInterface.get(), mUsage);
1064 if (res != OK) {
1065 ALOGE("%s: Unable to configure usage %08x for stream %d",
1066 __FUNCTION__, mUsage, mId);
1067 return res;
1068 }
1069
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001070 res = native_window_set_scaling_mode(mConsumerInterface.get(),
1071 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
1072 if (res != OK) {
1073 ALOGE("%s: Unable to configure stream scaling: %s (%d)",
1074 __FUNCTION__, strerror(-res), res);
1075 return res;
1076 }
1077
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001078 res = setTransform(0);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001079 if (res != OK) {
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001080 return res;
1081 }
1082
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001083 if (mFormat == HAL_PIXEL_FORMAT_BLOB) {
1084 res = native_window_set_buffers_geometry(mConsumerInterface.get(),
1085 mSize, 1, mFormat);
1086 if (res != OK) {
1087 ALOGE("%s: Unable to configure compressed stream buffer geometry"
Colin Crosse5729fa2014-03-21 15:04:25 -07001088 " %d x %d, size %zu for stream %d",
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001089 __FUNCTION__, mWidth, mHeight, mSize, mId);
1090 return res;
1091 }
1092 } else {
1093 res = native_window_set_buffers_geometry(mConsumerInterface.get(),
1094 mWidth, mHeight, mFormat);
1095 if (res != OK) {
1096 ALOGE("%s: Unable to configure stream buffer geometry"
1097 " %d x %d, format 0x%x for stream %d",
1098 __FUNCTION__, mWidth, mHeight, mFormat, mId);
1099 return res;
1100 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001101 }
1102
1103 int maxConsumerBuffers;
1104 res = mConsumerInterface->query(mConsumerInterface.get(),
1105 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &maxConsumerBuffers);
1106 if (res != OK) {
1107 ALOGE("%s: Unable to query consumer undequeued"
1108 " buffer count for stream %d", __FUNCTION__, mId);
1109 return res;
1110 }
1111 mMaxConsumerBuffers = maxConsumerBuffers;
1112
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001113 ALOGV("%s: Consumer wants %d buffers", __FUNCTION__,
1114 mMaxConsumerBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001115
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001116 mTotalBuffers = mMaxConsumerBuffers + mMaxProducerBuffers;
1117 mActiveBuffers = 0;
1118 mFrameCount = 0;
1119 mLastTimestamp = 0;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001120
1121 res = native_window_set_buffer_count(mConsumerInterface.get(),
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001122 mTotalBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001123 if (res != OK) {
1124 ALOGE("%s: Unable to set buffer count for stream %d",
1125 __FUNCTION__, mId);
1126 return res;
1127 }
1128
1129 // Register allocated buffers with HAL device
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001130 buffer_handle_t *buffers = new buffer_handle_t[mTotalBuffers];
1131 ANativeWindowBuffer **anwBuffers = new ANativeWindowBuffer*[mTotalBuffers];
1132 uint32_t bufferIdx = 0;
1133 for (; bufferIdx < mTotalBuffers; bufferIdx++) {
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001134 res = native_window_dequeue_buffer_and_wait(mConsumerInterface.get(),
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001135 &anwBuffers[bufferIdx]);
1136 if (res != OK) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001137 ALOGE("%s: Unable to dequeue buffer %d for initial registration for "
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001138 "stream %d", __FUNCTION__, bufferIdx, mId);
1139 goto cleanUpBuffers;
1140 }
1141
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001142 buffers[bufferIdx] = anwBuffers[bufferIdx]->handle;
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001143 ALOGV("%s: Buffer %p allocated", __FUNCTION__, (void*)buffers[bufferIdx]);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001144 }
1145
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001146 ALOGV("%s: Registering %d buffers with camera HAL", __FUNCTION__, mTotalBuffers);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001147 res = mHal2Device->ops->register_stream_buffers(mHal2Device,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001148 mId,
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001149 mTotalBuffers,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001150 buffers);
1151 if (res != OK) {
1152 ALOGE("%s: Unable to register buffers with HAL device for stream %d",
1153 __FUNCTION__, mId);
1154 } else {
1155 mState = ACTIVE;
1156 }
1157
1158cleanUpBuffers:
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001159 ALOGV("%s: Cleaning up %d buffers", __FUNCTION__, bufferIdx);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001160 for (uint32_t i = 0; i < bufferIdx; i++) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001161 res = mConsumerInterface->cancelBuffer(mConsumerInterface.get(),
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001162 anwBuffers[i], -1);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001163 if (res != OK) {
1164 ALOGE("%s: Unable to cancel buffer %d after registration",
1165 __FUNCTION__, i);
1166 }
1167 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001168 delete[] anwBuffers;
1169 delete[] buffers;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001170
1171 return res;
1172}
1173
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001174status_t Camera2Device::StreamAdapter::release() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001175 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001176 status_t res;
Eino-Ville Talvala02f84572013-04-23 15:16:57 -07001177 ALOGV("%s: Releasing stream %d (%d x %d, format %d)", __FUNCTION__, mId,
1178 mWidth, mHeight, mFormat);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001179 if (mState >= ALLOCATED) {
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001180 res = mHal2Device->ops->release_stream(mHal2Device, mId);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001181 if (res != OK) {
1182 ALOGE("%s: Unable to release stream %d",
1183 __FUNCTION__, mId);
1184 return res;
1185 }
1186 }
1187 if (mState >= CONNECTED) {
1188 res = native_window_api_disconnect(mConsumerInterface.get(),
1189 NATIVE_WINDOW_API_CAMERA);
Igor Murashkina1e5dcc2012-10-02 15:21:31 -07001190
1191 /* this is not an error. if client calling process dies,
1192 the window will also die and all calls to it will return
1193 DEAD_OBJECT, thus it's already "disconnected" */
1194 if (res == DEAD_OBJECT) {
1195 ALOGW("%s: While disconnecting stream %d from native window, the"
1196 " native window died from under us", __FUNCTION__, mId);
1197 }
1198 else if (res != OK) {
1199 ALOGE("%s: Unable to disconnect stream %d from native window (error %d %s)",
1200 __FUNCTION__, mId, res, strerror(-res));
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001201 return res;
1202 }
1203 }
1204 mId = -1;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001205 mState = RELEASED;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001206 return OK;
1207}
1208
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001209status_t Camera2Device::StreamAdapter::setTransform(int transform) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001210 ATRACE_CALL();
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001211 status_t res;
1212 if (mState < CONNECTED) {
1213 ALOGE("%s: Cannot set transform on unconnected stream", __FUNCTION__);
1214 return INVALID_OPERATION;
1215 }
1216 res = native_window_set_buffers_transform(mConsumerInterface.get(),
1217 transform);
1218 if (res != OK) {
1219 ALOGE("%s: Unable to configure stream transform to %x: %s (%d)",
1220 __FUNCTION__, transform, strerror(-res), res);
1221 }
1222 return res;
1223}
1224
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001225status_t Camera2Device::StreamAdapter::dump(int fd,
Igor Murashkinebe3f692012-10-12 16:56:11 -07001226 const Vector<String16>& /*args*/) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001227 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001228 String8 result = String8::format(" Stream %d: %d x %d, format 0x%x\n",
1229 mId, mWidth, mHeight, mFormat);
Kévin PETIT377b2ec2014-02-03 12:35:36 +00001230 result.appendFormat(" size %zu, usage 0x%x, requested format 0x%x\n",
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001231 mSize, mUsage, mFormatRequested);
1232 result.appendFormat(" total buffers: %d, dequeued buffers: %d\n",
1233 mTotalBuffers, mActiveBuffers);
Kévin PETIT377b2ec2014-02-03 12:35:36 +00001234 result.appendFormat(" frame count: %d, last timestamp %" PRId64 "\n",
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001235 mFrameCount, mLastTimestamp);
1236 write(fd, result.string(), result.size());
1237 return OK;
1238}
1239
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001240const camera2_stream_ops *Camera2Device::StreamAdapter::getStreamOps() {
1241 return static_cast<camera2_stream_ops *>(this);
1242}
1243
1244ANativeWindow* Camera2Device::StreamAdapter::toANW(
1245 const camera2_stream_ops_t *w) {
1246 return static_cast<const StreamAdapter*>(w)->mConsumerInterface.get();
1247}
1248
1249int Camera2Device::StreamAdapter::dequeue_buffer(const camera2_stream_ops_t *w,
1250 buffer_handle_t** buffer) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001251 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001252 int res;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001253 StreamAdapter* stream =
1254 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
1255 if (stream->mState != ACTIVE) {
1256 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001257 return INVALID_OPERATION;
1258 }
1259
1260 ANativeWindow *a = toANW(w);
1261 ANativeWindowBuffer* anb;
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001262 res = native_window_dequeue_buffer_and_wait(a, &anb);
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001263 if (res != OK) {
1264 ALOGE("Stream %d dequeue: Error from native_window: %s (%d)", stream->mId,
1265 strerror(-res), res);
1266 return res;
1267 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001268
1269 *buffer = &(anb->handle);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001270 stream->mActiveBuffers++;
1271
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001272 ALOGVV("Stream %d dequeue: Buffer %p dequeued", stream->mId, (void*)(**buffer));
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001273 return res;
1274}
1275
1276int Camera2Device::StreamAdapter::enqueue_buffer(const camera2_stream_ops_t* w,
1277 int64_t timestamp,
1278 buffer_handle_t* buffer) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001279 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001280 StreamAdapter *stream =
1281 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001282 stream->mFrameCount++;
1283 ALOGVV("Stream %d enqueue: Frame %d (%p) captured at %lld ns",
James Donga289bf62012-09-05 16:46:36 -07001284 stream->mId, stream->mFrameCount, (void*)(*buffer), timestamp);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001285 int state = stream->mState;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001286 if (state != ACTIVE) {
1287 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1288 return INVALID_OPERATION;
1289 }
1290 ANativeWindow *a = toANW(w);
1291 status_t err;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001292
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001293 err = native_window_set_buffers_timestamp(a, timestamp);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001294 if (err != OK) {
1295 ALOGE("%s: Error setting timestamp on native window: %s (%d)",
1296 __FUNCTION__, strerror(-err), err);
1297 return err;
1298 }
1299 err = a->queueBuffer(a,
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001300 container_of(buffer, ANativeWindowBuffer, handle), -1);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001301 if (err != OK) {
1302 ALOGE("%s: Error queueing buffer to native window: %s (%d)",
1303 __FUNCTION__, strerror(-err), err);
James Dong31d377b2012-08-09 17:43:46 -07001304 return err;
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001305 }
James Dong31d377b2012-08-09 17:43:46 -07001306
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001307 stream->mActiveBuffers--;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001308 stream->mLastTimestamp = timestamp;
James Dong31d377b2012-08-09 17:43:46 -07001309 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001310}
1311
1312int Camera2Device::StreamAdapter::cancel_buffer(const camera2_stream_ops_t* w,
1313 buffer_handle_t* buffer) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001314 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001315 StreamAdapter *stream =
1316 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001317 ALOGVV("Stream %d cancel: Buffer %p",
1318 stream->mId, (void*)(*buffer));
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001319 if (stream->mState != ACTIVE) {
1320 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001321 return INVALID_OPERATION;
1322 }
James Dong31d377b2012-08-09 17:43:46 -07001323
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001324 ANativeWindow *a = toANW(w);
James Dong31d377b2012-08-09 17:43:46 -07001325 int err = a->cancelBuffer(a,
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001326 container_of(buffer, ANativeWindowBuffer, handle), -1);
James Dong31d377b2012-08-09 17:43:46 -07001327 if (err != OK) {
1328 ALOGE("%s: Error canceling buffer to native window: %s (%d)",
1329 __FUNCTION__, strerror(-err), err);
1330 return err;
1331 }
1332
1333 stream->mActiveBuffers--;
1334 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001335}
1336
1337int Camera2Device::StreamAdapter::set_crop(const camera2_stream_ops_t* w,
1338 int left, int top, int right, int bottom) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001339 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001340 int state = static_cast<const StreamAdapter*>(w)->mState;
1341 if (state != ACTIVE) {
1342 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1343 return INVALID_OPERATION;
1344 }
1345 ANativeWindow *a = toANW(w);
1346 android_native_rect_t crop = { left, top, right, bottom };
1347 return native_window_set_crop(a, &crop);
1348}
1349
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001350/**
1351 * Camera2Device::ReprocessStreamAdapter
1352 */
1353
1354#ifndef container_of
1355#define container_of(ptr, type, member) \
1356 (type *)((char*)(ptr) - offsetof(type, member))
1357#endif
1358
1359Camera2Device::ReprocessStreamAdapter::ReprocessStreamAdapter(camera2_device_t *d):
1360 mState(RELEASED),
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001361 mHal2Device(d),
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001362 mId(-1),
1363 mWidth(0), mHeight(0), mFormat(0),
1364 mActiveBuffers(0),
1365 mFrameCount(0)
1366{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001367 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001368 camera2_stream_in_ops::acquire_buffer = acquire_buffer;
1369 camera2_stream_in_ops::release_buffer = release_buffer;
1370}
1371
1372Camera2Device::ReprocessStreamAdapter::~ReprocessStreamAdapter() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001373 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001374 if (mState != RELEASED) {
1375 release();
1376 }
1377}
1378
1379status_t Camera2Device::ReprocessStreamAdapter::connectToDevice(
1380 const sp<StreamAdapter> &outputStream) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001381 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001382 status_t res;
1383 ALOGV("%s: E", __FUNCTION__);
1384
1385 if (mState != RELEASED) return INVALID_OPERATION;
1386 if (outputStream == NULL) {
1387 ALOGE("%s: Null base stream passed to reprocess stream adapter",
1388 __FUNCTION__);
1389 return BAD_VALUE;
1390 }
1391
1392 mBaseStream = outputStream;
1393 mWidth = outputStream->getWidth();
1394 mHeight = outputStream->getHeight();
1395 mFormat = outputStream->getFormat();
1396
1397 ALOGV("%s: New reprocess stream parameters %d x %d, format 0x%x",
1398 __FUNCTION__, mWidth, mHeight, mFormat);
1399
1400 // Allocate device-side stream interface
1401
1402 uint32_t id;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001403 res = mHal2Device->ops->allocate_reprocess_stream_from_stream(mHal2Device,
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001404 outputStream->getId(), getStreamOps(),
1405 &id);
1406 if (res != OK) {
1407 ALOGE("%s: Device reprocess stream allocation failed: %s (%d)",
1408 __FUNCTION__, strerror(-res), res);
1409 return res;
1410 }
1411
1412 ALOGV("%s: Allocated reprocess stream id %d based on stream %d",
1413 __FUNCTION__, id, outputStream->getId());
1414
1415 mId = id;
1416
1417 mState = ACTIVE;
1418
1419 return OK;
1420}
1421
1422status_t Camera2Device::ReprocessStreamAdapter::release() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001423 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001424 status_t res;
1425 ALOGV("%s: Releasing stream %d", __FUNCTION__, mId);
1426 if (mState >= ACTIVE) {
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001427 res = mHal2Device->ops->release_reprocess_stream(mHal2Device, mId);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001428 if (res != OK) {
1429 ALOGE("%s: Unable to release stream %d",
1430 __FUNCTION__, mId);
1431 return res;
1432 }
1433 }
1434
1435 List<QueueEntry>::iterator s;
1436 for (s = mQueue.begin(); s != mQueue.end(); s++) {
1437 sp<BufferReleasedListener> listener = s->releaseListener.promote();
1438 if (listener != 0) listener->onBufferReleased(s->handle);
1439 }
1440 for (s = mInFlightQueue.begin(); s != mInFlightQueue.end(); s++) {
1441 sp<BufferReleasedListener> listener = s->releaseListener.promote();
1442 if (listener != 0) listener->onBufferReleased(s->handle);
1443 }
1444 mQueue.clear();
1445 mInFlightQueue.clear();
1446
1447 mState = RELEASED;
1448 return OK;
1449}
1450
1451status_t Camera2Device::ReprocessStreamAdapter::pushIntoStream(
1452 buffer_handle_t *handle, const wp<BufferReleasedListener> &releaseListener) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001453 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001454 // TODO: Some error checking here would be nice
1455 ALOGV("%s: Pushing buffer %p to stream", __FUNCTION__, (void*)(*handle));
1456
1457 QueueEntry entry;
1458 entry.handle = handle;
1459 entry.releaseListener = releaseListener;
1460 mQueue.push_back(entry);
1461 return OK;
1462}
1463
1464status_t Camera2Device::ReprocessStreamAdapter::dump(int fd,
Igor Murashkinebe3f692012-10-12 16:56:11 -07001465 const Vector<String16>& /*args*/) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001466 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001467 String8 result =
1468 String8::format(" Reprocess stream %d: %d x %d, fmt 0x%x\n",
1469 mId, mWidth, mHeight, mFormat);
1470 result.appendFormat(" acquired buffers: %d\n",
1471 mActiveBuffers);
1472 result.appendFormat(" frame count: %d\n",
1473 mFrameCount);
1474 write(fd, result.string(), result.size());
1475 return OK;
1476}
1477
1478const camera2_stream_in_ops *Camera2Device::ReprocessStreamAdapter::getStreamOps() {
1479 return static_cast<camera2_stream_in_ops *>(this);
1480}
1481
1482int Camera2Device::ReprocessStreamAdapter::acquire_buffer(
1483 const camera2_stream_in_ops_t *w,
1484 buffer_handle_t** buffer) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001485 ATRACE_CALL();
Igor Murashkinebe3f692012-10-12 16:56:11 -07001486
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001487 ReprocessStreamAdapter* stream =
1488 const_cast<ReprocessStreamAdapter*>(
1489 static_cast<const ReprocessStreamAdapter*>(w));
1490 if (stream->mState != ACTIVE) {
1491 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
1492 return INVALID_OPERATION;
1493 }
1494
1495 if (stream->mQueue.empty()) {
1496 *buffer = NULL;
1497 return OK;
1498 }
1499
1500 QueueEntry &entry = *(stream->mQueue.begin());
1501
1502 *buffer = entry.handle;
1503
1504 stream->mInFlightQueue.push_back(entry);
1505 stream->mQueue.erase(stream->mQueue.begin());
1506
1507 stream->mActiveBuffers++;
1508
1509 ALOGV("Stream %d acquire: Buffer %p acquired", stream->mId,
1510 (void*)(**buffer));
1511 return OK;
1512}
1513
1514int Camera2Device::ReprocessStreamAdapter::release_buffer(
1515 const camera2_stream_in_ops_t* w,
1516 buffer_handle_t* buffer) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001517 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001518 ReprocessStreamAdapter *stream =
1519 const_cast<ReprocessStreamAdapter*>(
1520 static_cast<const ReprocessStreamAdapter*>(w) );
1521 stream->mFrameCount++;
1522 ALOGV("Reprocess stream %d release: Frame %d (%p)",
1523 stream->mId, stream->mFrameCount, (void*)*buffer);
1524 int state = stream->mState;
1525 if (state != ACTIVE) {
1526 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1527 return INVALID_OPERATION;
1528 }
1529 stream->mActiveBuffers--;
1530
1531 List<QueueEntry>::iterator s;
1532 for (s = stream->mInFlightQueue.begin(); s != stream->mInFlightQueue.end(); s++) {
1533 if ( s->handle == buffer ) break;
1534 }
1535 if (s == stream->mInFlightQueue.end()) {
1536 ALOGE("%s: Can't find buffer %p in in-flight list!", __FUNCTION__,
1537 buffer);
1538 return INVALID_OPERATION;
1539 }
1540
1541 sp<BufferReleasedListener> listener = s->releaseListener.promote();
1542 if (listener != 0) {
1543 listener->onBufferReleased(s->handle);
1544 } else {
1545 ALOGE("%s: Can't free buffer - missing listener", __FUNCTION__);
1546 }
1547 stream->mInFlightQueue.erase(s);
1548
1549 return OK;
1550}
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001551
1552}; // namespace android