blob: 89c6b10e8abdb4077c11410513c25d4acad7782f [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;
Zhijun He204e3292014-07-14 17:09:23 -0700126 mDeviceVersion = device->common.version;
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700127
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700128 return OK;
129}
130
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700131status_t Camera2Device::disconnect() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700132 ATRACE_CALL();
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700133 status_t res = OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800134 if (mHal2Device) {
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700135 ALOGV("%s: Closing device for camera %d", __FUNCTION__, mId);
136
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800137 int inProgressCount = mHal2Device->ops->get_in_progress_count(mHal2Device);
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700138 if (inProgressCount > 0) {
139 ALOGW("%s: Closing camera device %d with %d requests in flight!",
140 __FUNCTION__, mId, inProgressCount);
141 }
Eino-Ville Talvalac62bb782012-09-24 13:44:07 -0700142 mReprocessStreams.clear();
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700143 mStreams.clear();
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800144 res = mHal2Device->common.close(&mHal2Device->common);
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700145 if (res != OK) {
146 ALOGE("%s: Could not close camera %d: %s (%d)",
147 __FUNCTION__,
148 mId, strerror(-res), res);
149 }
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800150 mHal2Device = NULL;
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700151 ALOGV("%s: Shutdown complete", __FUNCTION__);
152 }
153 return res;
154}
155
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700156status_t Camera2Device::dump(int fd, const Vector<String16>& args) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700157 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700158 String8 result;
Eino-Ville Talvala97197152012-08-06 14:25:19 -0700159 int detailLevel = 0;
160 int n = args.size();
161 String16 detailOption("-d");
162 for (int i = 0; i + 1 < n; i++) {
163 if (args[i] == detailOption) {
164 String8 levelStr(args[i+1]);
165 detailLevel = atoi(levelStr.string());
166 }
167 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700168
Eino-Ville Talvala603b12e2012-08-08 09:25:58 -0700169 result.appendFormat(" Camera2Device[%d] dump (detail level %d):\n",
170 mId, detailLevel);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700171
Eino-Ville Talvala97197152012-08-06 14:25:19 -0700172 if (detailLevel > 0) {
173 result = " Request queue contents:\n";
174 write(fd, result.string(), result.size());
175 mRequestQueue.dump(fd, args);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700176
Eino-Ville Talvala97197152012-08-06 14:25:19 -0700177 result = " Frame queue contents:\n";
178 write(fd, result.string(), result.size());
179 mFrameQueue.dump(fd, args);
180 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700181
182 result = " Active streams:\n";
183 write(fd, result.string(), result.size());
184 for (StreamList::iterator s = mStreams.begin(); s != mStreams.end(); s++) {
185 (*s)->dump(fd, args);
186 }
187
188 result = " HAL device dump:\n";
189 write(fd, result.string(), result.size());
190
191 status_t res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800192 res = mHal2Device->ops->dump(mHal2Device, fd);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700193
194 return res;
195}
196
Igor Murashkinbd02dd12013-02-13 15:53:56 -0800197const CameraMetadata& Camera2Device::info() const {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700198 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700199
200 return mDeviceInfo;
201}
202
Jianing Weicb0652e2014-03-12 18:29:36 -0700203status_t Camera2Device::capture(CameraMetadata &request, int64_t* /*lastFrameNumber*/) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700204 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700205 ALOGV("%s: E", __FUNCTION__);
206
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700207 mRequestQueue.enqueue(request.release());
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700208 return OK;
209}
210
Jianing Weicb0652e2014-03-12 18:29:36 -0700211status_t Camera2Device::captureList(const List<const CameraMetadata> &requests,
212 int64_t* /*lastFrameNumber*/) {
Jianing Wei90e59c92014-03-12 18:29:36 -0700213 ATRACE_CALL();
214 ALOGE("%s: Camera2Device burst capture not implemented", __FUNCTION__);
215 return INVALID_OPERATION;
216}
217
Jianing Weicb0652e2014-03-12 18:29:36 -0700218status_t Camera2Device::setStreamingRequest(const CameraMetadata &request,
219 int64_t* /*lastFrameNumber*/) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700220 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700221 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700222 CameraMetadata streamRequest(request);
223 return mRequestQueue.setStreamSlot(streamRequest.release());
224}
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700225
Jianing Weicb0652e2014-03-12 18:29:36 -0700226status_t Camera2Device::setStreamingRequestList(const List<const CameraMetadata> &requests,
227 int64_t* /*lastFrameNumber*/) {
Jianing Wei90e59c92014-03-12 18:29:36 -0700228 ATRACE_CALL();
229 ALOGE("%s, Camera2Device streaming burst not implemented", __FUNCTION__);
230 return INVALID_OPERATION;
231}
232
Jianing Weicb0652e2014-03-12 18:29:36 -0700233status_t Camera2Device::clearStreamingRequest(int64_t* /*lastFrameNumber*/) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700234 ATRACE_CALL();
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700235 return mRequestQueue.setStreamSlot(NULL);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700236}
237
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700238status_t Camera2Device::waitUntilRequestReceived(int32_t requestId, nsecs_t timeout) {
239 ATRACE_CALL();
240 return mRequestQueue.waitForDequeue(requestId, timeout);
241}
242
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700243status_t Camera2Device::createStream(sp<ANativeWindow> consumer,
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700244 uint32_t width, uint32_t height, int format, size_t size, int *id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700245 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700246 status_t res;
247 ALOGV("%s: E", __FUNCTION__);
248
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800249 sp<StreamAdapter> stream = new StreamAdapter(mHal2Device);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700250
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700251 res = stream->connectToDevice(consumer, width, height, format, size);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700252 if (res != OK) {
253 ALOGE("%s: Camera %d: Unable to create stream (%d x %d, format %x):"
254 "%s (%d)",
255 __FUNCTION__, mId, width, height, format, strerror(-res), res);
256 return res;
257 }
258
259 *id = stream->getId();
260
261 mStreams.push_back(stream);
262 return OK;
263}
264
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700265status_t Camera2Device::createReprocessStreamFromStream(int outputId, int *id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700266 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700267 status_t res;
268 ALOGV("%s: E", __FUNCTION__);
269
270 bool found = false;
271 StreamList::iterator streamI;
272 for (streamI = mStreams.begin();
273 streamI != mStreams.end(); streamI++) {
274 if ((*streamI)->getId() == outputId) {
275 found = true;
276 break;
277 }
278 }
279 if (!found) {
280 ALOGE("%s: Camera %d: Output stream %d doesn't exist; can't create "
281 "reprocess stream from it!", __FUNCTION__, mId, outputId);
282 return BAD_VALUE;
283 }
284
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800285 sp<ReprocessStreamAdapter> stream = new ReprocessStreamAdapter(mHal2Device);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700286
287 res = stream->connectToDevice((*streamI));
288 if (res != OK) {
289 ALOGE("%s: Camera %d: Unable to create reprocessing stream from "\
290 "stream %d: %s (%d)", __FUNCTION__, mId, outputId,
291 strerror(-res), res);
292 return res;
293 }
294
295 *id = stream->getId();
296
297 mReprocessStreams.push_back(stream);
298 return OK;
299}
300
301
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700302status_t Camera2Device::getStreamInfo(int id,
303 uint32_t *width, uint32_t *height, uint32_t *format) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700304 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700305 ALOGV("%s: E", __FUNCTION__);
306 bool found = false;
307 StreamList::iterator streamI;
308 for (streamI = mStreams.begin();
309 streamI != mStreams.end(); streamI++) {
310 if ((*streamI)->getId() == id) {
311 found = true;
312 break;
313 }
314 }
315 if (!found) {
316 ALOGE("%s: Camera %d: Stream %d does not exist",
317 __FUNCTION__, mId, id);
318 return BAD_VALUE;
319 }
320
321 if (width) *width = (*streamI)->getWidth();
322 if (height) *height = (*streamI)->getHeight();
323 if (format) *format = (*streamI)->getFormat();
324
325 return OK;
326}
327
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -0700328status_t Camera2Device::setStreamTransform(int id,
329 int transform) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700330 ATRACE_CALL();
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -0700331 ALOGV("%s: E", __FUNCTION__);
332 bool found = false;
333 StreamList::iterator streamI;
334 for (streamI = mStreams.begin();
335 streamI != mStreams.end(); streamI++) {
336 if ((*streamI)->getId() == id) {
337 found = true;
338 break;
339 }
340 }
341 if (!found) {
342 ALOGE("%s: Camera %d: Stream %d does not exist",
343 __FUNCTION__, mId, id);
344 return BAD_VALUE;
345 }
346
347 return (*streamI)->setTransform(transform);
348}
349
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700350status_t Camera2Device::deleteStream(int id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700351 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700352 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700353 bool found = false;
354 for (StreamList::iterator streamI = mStreams.begin();
355 streamI != mStreams.end(); streamI++) {
356 if ((*streamI)->getId() == id) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700357 status_t res = (*streamI)->release();
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700358 if (res != OK) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700359 ALOGE("%s: Unable to release stream %d from HAL device: "
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700360 "%s (%d)", __FUNCTION__, id, strerror(-res), res);
361 return res;
362 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700363 mStreams.erase(streamI);
364 found = true;
365 break;
366 }
367 }
368 if (!found) {
369 ALOGE("%s: Camera %d: Unable to find stream %d to delete",
370 __FUNCTION__, mId, id);
371 return BAD_VALUE;
372 }
373 return OK;
374}
375
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700376status_t Camera2Device::deleteReprocessStream(int id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700377 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700378 ALOGV("%s: E", __FUNCTION__);
379 bool found = false;
380 for (ReprocessStreamList::iterator streamI = mReprocessStreams.begin();
381 streamI != mReprocessStreams.end(); streamI++) {
382 if ((*streamI)->getId() == id) {
383 status_t res = (*streamI)->release();
384 if (res != OK) {
385 ALOGE("%s: Unable to release reprocess stream %d from "
386 "HAL device: %s (%d)", __FUNCTION__, id,
387 strerror(-res), res);
388 return res;
389 }
390 mReprocessStreams.erase(streamI);
391 found = true;
392 break;
393 }
394 }
395 if (!found) {
396 ALOGE("%s: Camera %d: Unable to find stream %d to delete",
397 __FUNCTION__, mId, id);
398 return BAD_VALUE;
399 }
400 return OK;
401}
402
403
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700404status_t Camera2Device::createDefaultRequest(int templateId,
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700405 CameraMetadata *request) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700406 ATRACE_CALL();
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700407 status_t err;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700408 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700409 camera_metadata_t *rawRequest;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800410 err = mHal2Device->ops->construct_default_request(
411 mHal2Device, templateId, &rawRequest);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700412 request->acquire(rawRequest);
413 return err;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700414}
415
416status_t Camera2Device::waitUntilDrained() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700417 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700418 static const uint32_t kSleepTime = 50000; // 50 ms
419 static const uint32_t kMaxSleepTime = 10000000; // 10 s
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700420 ALOGV("%s: Camera %d: Starting wait", __FUNCTION__, mId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700421 if (mRequestQueue.getBufferCount() ==
422 CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS) return INVALID_OPERATION;
423
424 // TODO: Set up notifications from HAL, instead of sleeping here
425 uint32_t totalTime = 0;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800426 while (mHal2Device->ops->get_in_progress_count(mHal2Device) > 0) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700427 usleep(kSleepTime);
428 totalTime += kSleepTime;
429 if (totalTime > kMaxSleepTime) {
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700430 ALOGE("%s: Waited %d us, %d requests still in flight", __FUNCTION__,
Alex Rayf0eeb532013-03-17 03:23:18 -0700431 totalTime, mHal2Device->ops->get_in_progress_count(mHal2Device));
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700432 return TIMED_OUT;
433 }
434 }
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700435 ALOGV("%s: Camera %d: HAL is idle", __FUNCTION__, mId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700436 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700437}
438
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700439status_t Camera2Device::setNotifyCallback(NotificationListener *listener) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700440 ATRACE_CALL();
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700441 status_t res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800442 res = mHal2Device->ops->set_notify_callback(mHal2Device, notificationCallback,
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700443 reinterpret_cast<void*>(listener) );
444 if (res != OK) {
445 ALOGE("%s: Unable to set notification callback!", __FUNCTION__);
446 }
447 return res;
448}
449
Eino-Ville Talvala46910bd2013-07-18 19:15:17 -0700450bool Camera2Device::willNotify3A() {
451 return true;
452}
453
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700454void Camera2Device::notificationCallback(int32_t msg_type,
455 int32_t ext1,
456 int32_t ext2,
457 int32_t ext3,
458 void *user) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700459 ATRACE_CALL();
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700460 NotificationListener *listener = reinterpret_cast<NotificationListener*>(user);
461 ALOGV("%s: Notification %d, arguments %d, %d, %d", __FUNCTION__, msg_type,
462 ext1, ext2, ext3);
463 if (listener != NULL) {
464 switch (msg_type) {
465 case CAMERA2_MSG_ERROR:
Jianing Weicb0652e2014-03-12 18:29:36 -0700466 // TODO: This needs to be fixed. ext2 and ext3 need to be considered.
467 listener->notifyError(
468 ((ext1 == CAMERA2_MSG_ERROR_DEVICE)
469 || (ext1 == CAMERA2_MSG_ERROR_HARDWARE)) ?
470 ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE :
471 ICameraDeviceCallbacks::ERROR_CAMERA_SERVICE,
472 CaptureResultExtras());
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700473 break;
474 case CAMERA2_MSG_SHUTTER: {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700475 // TODO: Only needed for camera2 API, which is unsupported
476 // by HAL2 directly.
477 // nsecs_t timestamp = (nsecs_t)ext2 | ((nsecs_t)(ext3) << 32 );
478 // listener->notifyShutter(requestId, timestamp);
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700479 break;
480 }
481 case CAMERA2_MSG_AUTOFOCUS:
482 listener->notifyAutoFocus(ext1, ext2);
483 break;
484 case CAMERA2_MSG_AUTOEXPOSURE:
485 listener->notifyAutoExposure(ext1, ext2);
486 break;
487 case CAMERA2_MSG_AUTOWB:
488 listener->notifyAutoWhitebalance(ext1, ext2);
489 break;
490 default:
491 ALOGE("%s: Unknown notification %d (arguments %d, %d, %d)!",
492 __FUNCTION__, msg_type, ext1, ext2, ext3);
493 }
494 }
495}
496
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -0700497status_t Camera2Device::waitForNextFrame(nsecs_t timeout) {
498 return mFrameQueue.waitForBuffer(timeout);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700499}
500
Jianing Weicb0652e2014-03-12 18:29:36 -0700501status_t Camera2Device::getNextResult(CaptureResult *result) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700502 ATRACE_CALL();
Jianing Weicb0652e2014-03-12 18:29:36 -0700503 ALOGV("%s: get CaptureResult", __FUNCTION__);
504 if (result == NULL) {
505 ALOGE("%s: result pointer is NULL", __FUNCTION__);
506 return BAD_VALUE;
507 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700508 status_t res;
509 camera_metadata_t *rawFrame;
510 res = mFrameQueue.dequeue(&rawFrame);
Jianing Weicb0652e2014-03-12 18:29:36 -0700511 if (rawFrame == NULL) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700512 return NOT_ENOUGH_DATA;
513 } else if (res == OK) {
Jianing Weicb0652e2014-03-12 18:29:36 -0700514 result->mMetadata.acquire(rawFrame);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700515 }
Jianing Weicb0652e2014-03-12 18:29:36 -0700516
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700517 return res;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700518}
519
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700520status_t Camera2Device::triggerAutofocus(uint32_t id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700521 ATRACE_CALL();
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700522 status_t res;
523 ALOGV("%s: Triggering autofocus, id %d", __FUNCTION__, id);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800524 res = mHal2Device->ops->trigger_action(mHal2Device,
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700525 CAMERA2_TRIGGER_AUTOFOCUS, id, 0);
526 if (res != OK) {
527 ALOGE("%s: Error triggering autofocus (id %d)",
528 __FUNCTION__, id);
529 }
530 return res;
531}
532
533status_t Camera2Device::triggerCancelAutofocus(uint32_t id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700534 ATRACE_CALL();
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700535 status_t res;
536 ALOGV("%s: Canceling autofocus, id %d", __FUNCTION__, id);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800537 res = mHal2Device->ops->trigger_action(mHal2Device,
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700538 CAMERA2_TRIGGER_CANCEL_AUTOFOCUS, id, 0);
539 if (res != OK) {
540 ALOGE("%s: Error canceling autofocus (id %d)",
541 __FUNCTION__, id);
542 }
543 return res;
544}
545
546status_t Camera2Device::triggerPrecaptureMetering(uint32_t id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700547 ATRACE_CALL();
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700548 status_t res;
549 ALOGV("%s: Triggering precapture metering, id %d", __FUNCTION__, id);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800550 res = mHal2Device->ops->trigger_action(mHal2Device,
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700551 CAMERA2_TRIGGER_PRECAPTURE_METERING, id, 0);
552 if (res != OK) {
553 ALOGE("%s: Error triggering precapture metering (id %d)",
554 __FUNCTION__, id);
555 }
556 return res;
557}
558
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700559status_t Camera2Device::pushReprocessBuffer(int reprocessStreamId,
560 buffer_handle_t *buffer, wp<BufferReleasedListener> listener) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700561 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700562 ALOGV("%s: E", __FUNCTION__);
563 bool found = false;
564 status_t res = OK;
565 for (ReprocessStreamList::iterator streamI = mReprocessStreams.begin();
566 streamI != mReprocessStreams.end(); streamI++) {
567 if ((*streamI)->getId() == reprocessStreamId) {
568 res = (*streamI)->pushIntoStream(buffer, listener);
569 if (res != OK) {
570 ALOGE("%s: Unable to push buffer to reprocess stream %d: %s (%d)",
571 __FUNCTION__, reprocessStreamId, strerror(-res), res);
572 return res;
573 }
574 found = true;
575 break;
576 }
577 }
578 if (!found) {
579 ALOGE("%s: Camera %d: Unable to find reprocess stream %d",
580 __FUNCTION__, mId, reprocessStreamId);
581 res = BAD_VALUE;
582 }
583 return res;
584}
585
Jianing Weicb0652e2014-03-12 18:29:36 -0700586status_t Camera2Device::flush(int64_t* /*lastFrameNumber*/) {
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -0700587 ATRACE_CALL();
588
589 mRequestQueue.clear();
590 return waitUntilDrained();
591}
592
Zhijun He204e3292014-07-14 17:09:23 -0700593uint32_t Camera2Device::getDeviceVersion() {
594 ATRACE_CALL();
595 return mDeviceVersion;
596}
597
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700598/**
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700599 * Camera2Device::MetadataQueue
600 */
601
602Camera2Device::MetadataQueue::MetadataQueue():
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800603 mHal2Device(NULL),
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700604 mFrameCount(0),
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700605 mLatestRequestId(0),
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700606 mCount(0),
607 mStreamSlotCount(0),
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -0700608 mSignalConsumer(true)
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700609{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700610 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700611 camera2_request_queue_src_ops::dequeue_request = consumer_dequeue;
612 camera2_request_queue_src_ops::request_count = consumer_buffer_count;
613 camera2_request_queue_src_ops::free_request = consumer_free;
614
615 camera2_frame_queue_dst_ops::dequeue_frame = producer_dequeue;
616 camera2_frame_queue_dst_ops::cancel_frame = producer_cancel;
617 camera2_frame_queue_dst_ops::enqueue_frame = producer_enqueue;
618}
619
620Camera2Device::MetadataQueue::~MetadataQueue() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700621 ATRACE_CALL();
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -0700622 clear();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700623}
624
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700625// Connect to camera2 HAL as consumer (input requests/reprocessing)
626status_t Camera2Device::MetadataQueue::setConsumerDevice(camera2_device_t *d) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700627 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700628 status_t res;
629 res = d->ops->set_request_queue_src_ops(d,
630 this);
631 if (res != OK) return res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800632 mHal2Device = d;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700633 return OK;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700634}
635
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700636status_t Camera2Device::MetadataQueue::setProducerDevice(camera2_device_t *d) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700637 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700638 status_t res;
639 res = d->ops->set_frame_queue_dst_ops(d,
640 this);
641 return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700642}
643
644// Real interfaces
645status_t Camera2Device::MetadataQueue::enqueue(camera_metadata_t *buf) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700646 ATRACE_CALL();
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700647 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700648 Mutex::Autolock l(mMutex);
649
650 mCount++;
651 mEntries.push_back(buf);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700652
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700653 return signalConsumerLocked();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700654}
655
656int Camera2Device::MetadataQueue::getBufferCount() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700657 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700658 Mutex::Autolock l(mMutex);
659 if (mStreamSlotCount > 0) {
660 return CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS;
661 }
662 return mCount;
663}
664
665status_t Camera2Device::MetadataQueue::dequeue(camera_metadata_t **buf,
666 bool incrementCount)
667{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700668 ATRACE_CALL();
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700669 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700670 status_t res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700671 Mutex::Autolock l(mMutex);
672
673 if (mCount == 0) {
674 if (mStreamSlotCount == 0) {
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700675 ALOGVV("%s: Empty", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700676 *buf = NULL;
677 mSignalConsumer = true;
678 return OK;
679 }
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700680 ALOGVV("%s: Streaming %d frames to queue", __FUNCTION__,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700681 mStreamSlotCount);
682
683 for (List<camera_metadata_t*>::iterator slotEntry = mStreamSlot.begin();
684 slotEntry != mStreamSlot.end();
685 slotEntry++ ) {
686 size_t entries = get_camera_metadata_entry_count(*slotEntry);
687 size_t dataBytes = get_camera_metadata_data_count(*slotEntry);
688
689 camera_metadata_t *copy =
690 allocate_camera_metadata(entries, dataBytes);
691 append_camera_metadata(copy, *slotEntry);
692 mEntries.push_back(copy);
693 }
694 mCount = mStreamSlotCount;
695 }
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700696 ALOGVV("MetadataQueue: deque (%d buffers)", mCount);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700697 camera_metadata_t *b = *(mEntries.begin());
698 mEntries.erase(mEntries.begin());
699
700 if (incrementCount) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700701 ATRACE_INT("cam2_request", mFrameCount);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700702 camera_metadata_entry_t frameCount;
703 res = find_camera_metadata_entry(b,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700704 ANDROID_REQUEST_FRAME_COUNT,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700705 &frameCount);
706 if (res != OK) {
707 ALOGE("%s: Unable to add frame count: %s (%d)",
708 __FUNCTION__, strerror(-res), res);
709 } else {
710 *frameCount.data.i32 = mFrameCount;
711 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700712 mFrameCount++;
713 }
714
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700715 // Check for request ID, and if present, signal waiters.
716 camera_metadata_entry_t requestId;
717 res = find_camera_metadata_entry(b,
718 ANDROID_REQUEST_ID,
719 &requestId);
720 if (res == OK) {
721 mLatestRequestId = requestId.data.i32[0];
722 mNewRequestId.signal();
723 }
724
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700725 *buf = b;
726 mCount--;
727
728 return OK;
729}
730
731status_t Camera2Device::MetadataQueue::waitForBuffer(nsecs_t timeout)
732{
733 Mutex::Autolock l(mMutex);
734 status_t res;
735 while (mCount == 0) {
736 res = notEmpty.waitRelative(mMutex,timeout);
737 if (res != OK) return res;
738 }
739 return OK;
740}
741
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700742status_t Camera2Device::MetadataQueue::waitForDequeue(int32_t id,
743 nsecs_t timeout) {
744 Mutex::Autolock l(mMutex);
745 status_t res;
746 while (mLatestRequestId != id) {
747 nsecs_t startTime = systemTime();
748
749 res = mNewRequestId.waitRelative(mMutex, timeout);
750 if (res != OK) return res;
751
752 timeout -= (systemTime() - startTime);
753 }
754
755 return OK;
756}
757
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700758status_t Camera2Device::MetadataQueue::setStreamSlot(camera_metadata_t *buf)
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);
763 if (buf == NULL) {
764 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
765 mStreamSlotCount = 0;
766 return OK;
767 }
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700768 camera_metadata_t *buf2 = clone_camera_metadata(buf);
769 if (!buf2) {
770 ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__);
771 return NO_MEMORY;
772 }
773
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700774 if (mStreamSlotCount > 1) {
775 List<camera_metadata_t*>::iterator deleter = ++mStreamSlot.begin();
776 freeBuffers(++mStreamSlot.begin(), mStreamSlot.end());
777 mStreamSlotCount = 1;
778 }
779 if (mStreamSlotCount == 1) {
780 free_camera_metadata( *(mStreamSlot.begin()) );
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700781 *(mStreamSlot.begin()) = buf2;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700782 } else {
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700783 mStreamSlot.push_front(buf2);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700784 mStreamSlotCount = 1;
785 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700786 return signalConsumerLocked();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700787}
788
789status_t Camera2Device::MetadataQueue::setStreamSlot(
790 const List<camera_metadata_t*> &bufs)
791{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700792 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700793 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700794 Mutex::Autolock l(mMutex);
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700795
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700796 if (mStreamSlotCount > 0) {
797 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
798 }
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700799 mStreamSlotCount = 0;
800 for (List<camera_metadata_t*>::const_iterator r = bufs.begin();
801 r != bufs.end(); r++) {
802 camera_metadata_t *r2 = clone_camera_metadata(*r);
803 if (!r2) {
804 ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__);
805 return NO_MEMORY;
806 }
807 mStreamSlot.push_back(r2);
808 mStreamSlotCount++;
809 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700810 return signalConsumerLocked();
811}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700812
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -0700813status_t Camera2Device::MetadataQueue::clear()
814{
815 ATRACE_CALL();
816 ALOGV("%s: E", __FUNCTION__);
817
818 Mutex::Autolock l(mMutex);
819
820 // Clear streaming slot
821 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
822 mStreamSlotCount = 0;
823
824 // Clear request queue
825 freeBuffers(mEntries.begin(), mEntries.end());
826 mCount = 0;
827 return OK;
828}
829
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700830status_t Camera2Device::MetadataQueue::dump(int fd,
Igor Murashkinebe3f692012-10-12 16:56:11 -0700831 const Vector<String16>& /*args*/) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700832 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700833 String8 result;
834 status_t notLocked;
835 notLocked = mMutex.tryLock();
836 if (notLocked) {
837 result.append(" (Unable to lock queue mutex)\n");
838 }
839 result.appendFormat(" Current frame number: %d\n", mFrameCount);
840 if (mStreamSlotCount == 0) {
841 result.append(" Stream slot: Empty\n");
842 write(fd, result.string(), result.size());
843 } else {
Kévin PETIT377b2ec2014-02-03 12:35:36 +0000844 result.appendFormat(" Stream slot: %zu entries\n",
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700845 mStreamSlot.size());
846 int i = 0;
847 for (List<camera_metadata_t*>::iterator r = mStreamSlot.begin();
848 r != mStreamSlot.end(); r++) {
849 result = String8::format(" Stream slot buffer %d:\n", i);
850 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700851 dump_indented_camera_metadata(*r, fd, 2, 10);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700852 i++;
853 }
854 }
855 if (mEntries.size() == 0) {
856 result = " Main queue is empty\n";
857 write(fd, result.string(), result.size());
858 } else {
Kévin PETIT377b2ec2014-02-03 12:35:36 +0000859 result = String8::format(" Main queue has %zu entries:\n",
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700860 mEntries.size());
861 int i = 0;
862 for (List<camera_metadata_t*>::iterator r = mEntries.begin();
863 r != mEntries.end(); r++) {
864 result = String8::format(" Queue entry %d:\n", i);
865 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700866 dump_indented_camera_metadata(*r, fd, 2, 10);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700867 i++;
868 }
869 }
870
871 if (notLocked == 0) {
872 mMutex.unlock();
873 }
874
875 return OK;
876}
877
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700878status_t Camera2Device::MetadataQueue::signalConsumerLocked() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700879 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700880 status_t res = OK;
881 notEmpty.signal();
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800882 if (mSignalConsumer && mHal2Device != NULL) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700883 mSignalConsumer = false;
884
885 mMutex.unlock();
886 ALOGV("%s: Signaling consumer", __FUNCTION__);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800887 res = mHal2Device->ops->notify_request_queue_not_empty(mHal2Device);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700888 mMutex.lock();
889 }
890 return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700891}
892
893status_t Camera2Device::MetadataQueue::freeBuffers(
894 List<camera_metadata_t*>::iterator start,
895 List<camera_metadata_t*>::iterator end)
896{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700897 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700898 while (start != end) {
899 free_camera_metadata(*start);
900 start = mStreamSlot.erase(start);
901 }
902 return OK;
903}
904
905Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
906 const camera2_request_queue_src_ops_t *q)
907{
908 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
909 return const_cast<MetadataQueue*>(cmq);
910}
911
912Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
913 const camera2_frame_queue_dst_ops_t *q)
914{
915 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
916 return const_cast<MetadataQueue*>(cmq);
917}
918
919int Camera2Device::MetadataQueue::consumer_buffer_count(
920 const camera2_request_queue_src_ops_t *q)
921{
922 MetadataQueue *queue = getInstance(q);
923 return queue->getBufferCount();
924}
925
926int Camera2Device::MetadataQueue::consumer_dequeue(
927 const camera2_request_queue_src_ops_t *q,
928 camera_metadata_t **buffer)
929{
930 MetadataQueue *queue = getInstance(q);
931 return queue->dequeue(buffer, true);
932}
933
934int Camera2Device::MetadataQueue::consumer_free(
935 const camera2_request_queue_src_ops_t *q,
936 camera_metadata_t *old_buffer)
937{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700938 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700939 MetadataQueue *queue = getInstance(q);
Igor Murashkinebe3f692012-10-12 16:56:11 -0700940 (void)queue;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700941 free_camera_metadata(old_buffer);
942 return OK;
943}
944
945int Camera2Device::MetadataQueue::producer_dequeue(
Igor Murashkinebe3f692012-10-12 16:56:11 -0700946 const camera2_frame_queue_dst_ops_t * /*q*/,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700947 size_t entries, size_t bytes,
948 camera_metadata_t **buffer)
949{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700950 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700951 camera_metadata_t *new_buffer =
952 allocate_camera_metadata(entries, bytes);
953 if (new_buffer == NULL) return NO_MEMORY;
954 *buffer = new_buffer;
955 return OK;
956}
957
958int Camera2Device::MetadataQueue::producer_cancel(
Igor Murashkinebe3f692012-10-12 16:56:11 -0700959 const camera2_frame_queue_dst_ops_t * /*q*/,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700960 camera_metadata_t *old_buffer)
961{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700962 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700963 free_camera_metadata(old_buffer);
964 return OK;
965}
966
967int Camera2Device::MetadataQueue::producer_enqueue(
968 const camera2_frame_queue_dst_ops_t *q,
969 camera_metadata_t *filled_buffer)
970{
971 MetadataQueue *queue = getInstance(q);
972 return queue->enqueue(filled_buffer);
973}
974
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700975/**
976 * Camera2Device::StreamAdapter
977 */
978
979#ifndef container_of
980#define container_of(ptr, type, member) \
981 (type *)((char*)(ptr) - offsetof(type, member))
982#endif
983
984Camera2Device::StreamAdapter::StreamAdapter(camera2_device_t *d):
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700985 mState(RELEASED),
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800986 mHal2Device(d),
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700987 mId(-1),
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700988 mWidth(0), mHeight(0), mFormat(0), mSize(0), mUsage(0),
989 mMaxProducerBuffers(0), mMaxConsumerBuffers(0),
990 mTotalBuffers(0),
991 mFormatRequested(0),
992 mActiveBuffers(0),
993 mFrameCount(0),
994 mLastTimestamp(0)
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700995{
996 camera2_stream_ops::dequeue_buffer = dequeue_buffer;
997 camera2_stream_ops::enqueue_buffer = enqueue_buffer;
998 camera2_stream_ops::cancel_buffer = cancel_buffer;
999 camera2_stream_ops::set_crop = set_crop;
1000}
1001
1002Camera2Device::StreamAdapter::~StreamAdapter() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001003 ATRACE_CALL();
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001004 if (mState != RELEASED) {
1005 release();
1006 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001007}
1008
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001009status_t Camera2Device::StreamAdapter::connectToDevice(
1010 sp<ANativeWindow> consumer,
1011 uint32_t width, uint32_t height, int format, size_t size) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001012 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001013 status_t res;
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -07001014 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001015
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001016 if (mState != RELEASED) return INVALID_OPERATION;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001017 if (consumer == NULL) {
1018 ALOGE("%s: Null consumer passed to stream adapter", __FUNCTION__);
1019 return BAD_VALUE;
1020 }
1021
Colin Crosse5729fa2014-03-21 15:04:25 -07001022 ALOGV("%s: New stream parameters %d x %d, format 0x%x, size %zu",
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001023 __FUNCTION__, width, height, format, size);
1024
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001025 mConsumerInterface = consumer;
1026 mWidth = width;
1027 mHeight = height;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001028 mSize = (format == HAL_PIXEL_FORMAT_BLOB) ? size : 0;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001029 mFormatRequested = format;
1030
1031 // Allocate device-side stream interface
1032
1033 uint32_t id;
1034 uint32_t formatActual;
1035 uint32_t usage;
1036 uint32_t maxBuffers = 2;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001037 res = mHal2Device->ops->allocate_stream(mHal2Device,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001038 mWidth, mHeight, mFormatRequested, getStreamOps(),
1039 &id, &formatActual, &usage, &maxBuffers);
1040 if (res != OK) {
1041 ALOGE("%s: Device stream allocation failed: %s (%d)",
1042 __FUNCTION__, strerror(-res), res);
1043 return res;
1044 }
1045
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001046 ALOGV("%s: Allocated stream id %d, actual format 0x%x, "
1047 "usage 0x%x, producer wants %d buffers", __FUNCTION__,
1048 id, formatActual, usage, maxBuffers);
1049
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001050 mId = id;
1051 mFormat = formatActual;
1052 mUsage = usage;
1053 mMaxProducerBuffers = maxBuffers;
1054
1055 mState = ALLOCATED;
1056
1057 // Configure consumer-side ANativeWindow interface
1058 res = native_window_api_connect(mConsumerInterface.get(),
1059 NATIVE_WINDOW_API_CAMERA);
1060 if (res != OK) {
1061 ALOGE("%s: Unable to connect to native window for stream %d",
1062 __FUNCTION__, mId);
1063
1064 return res;
1065 }
1066
1067 mState = CONNECTED;
1068
1069 res = native_window_set_usage(mConsumerInterface.get(), mUsage);
1070 if (res != OK) {
1071 ALOGE("%s: Unable to configure usage %08x for stream %d",
1072 __FUNCTION__, mUsage, mId);
1073 return res;
1074 }
1075
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001076 res = native_window_set_scaling_mode(mConsumerInterface.get(),
1077 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
1078 if (res != OK) {
1079 ALOGE("%s: Unable to configure stream scaling: %s (%d)",
1080 __FUNCTION__, strerror(-res), res);
1081 return res;
1082 }
1083
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001084 res = setTransform(0);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001085 if (res != OK) {
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001086 return res;
1087 }
1088
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001089 if (mFormat == HAL_PIXEL_FORMAT_BLOB) {
1090 res = native_window_set_buffers_geometry(mConsumerInterface.get(),
1091 mSize, 1, mFormat);
1092 if (res != OK) {
1093 ALOGE("%s: Unable to configure compressed stream buffer geometry"
Colin Crosse5729fa2014-03-21 15:04:25 -07001094 " %d x %d, size %zu for stream %d",
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001095 __FUNCTION__, mWidth, mHeight, mSize, mId);
1096 return res;
1097 }
1098 } else {
1099 res = native_window_set_buffers_geometry(mConsumerInterface.get(),
1100 mWidth, mHeight, mFormat);
1101 if (res != OK) {
1102 ALOGE("%s: Unable to configure stream buffer geometry"
1103 " %d x %d, format 0x%x for stream %d",
1104 __FUNCTION__, mWidth, mHeight, mFormat, mId);
1105 return res;
1106 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001107 }
1108
1109 int maxConsumerBuffers;
1110 res = mConsumerInterface->query(mConsumerInterface.get(),
1111 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &maxConsumerBuffers);
1112 if (res != OK) {
1113 ALOGE("%s: Unable to query consumer undequeued"
1114 " buffer count for stream %d", __FUNCTION__, mId);
1115 return res;
1116 }
1117 mMaxConsumerBuffers = maxConsumerBuffers;
1118
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001119 ALOGV("%s: Consumer wants %d buffers", __FUNCTION__,
1120 mMaxConsumerBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001121
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001122 mTotalBuffers = mMaxConsumerBuffers + mMaxProducerBuffers;
1123 mActiveBuffers = 0;
1124 mFrameCount = 0;
1125 mLastTimestamp = 0;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001126
1127 res = native_window_set_buffer_count(mConsumerInterface.get(),
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001128 mTotalBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001129 if (res != OK) {
1130 ALOGE("%s: Unable to set buffer count for stream %d",
1131 __FUNCTION__, mId);
1132 return res;
1133 }
1134
1135 // Register allocated buffers with HAL device
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001136 buffer_handle_t *buffers = new buffer_handle_t[mTotalBuffers];
1137 ANativeWindowBuffer **anwBuffers = new ANativeWindowBuffer*[mTotalBuffers];
1138 uint32_t bufferIdx = 0;
1139 for (; bufferIdx < mTotalBuffers; bufferIdx++) {
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001140 res = native_window_dequeue_buffer_and_wait(mConsumerInterface.get(),
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001141 &anwBuffers[bufferIdx]);
1142 if (res != OK) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001143 ALOGE("%s: Unable to dequeue buffer %d for initial registration for "
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001144 "stream %d", __FUNCTION__, bufferIdx, mId);
1145 goto cleanUpBuffers;
1146 }
1147
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001148 buffers[bufferIdx] = anwBuffers[bufferIdx]->handle;
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001149 ALOGV("%s: Buffer %p allocated", __FUNCTION__, (void*)buffers[bufferIdx]);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001150 }
1151
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001152 ALOGV("%s: Registering %d buffers with camera HAL", __FUNCTION__, mTotalBuffers);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001153 res = mHal2Device->ops->register_stream_buffers(mHal2Device,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001154 mId,
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001155 mTotalBuffers,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001156 buffers);
1157 if (res != OK) {
1158 ALOGE("%s: Unable to register buffers with HAL device for stream %d",
1159 __FUNCTION__, mId);
1160 } else {
1161 mState = ACTIVE;
1162 }
1163
1164cleanUpBuffers:
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001165 ALOGV("%s: Cleaning up %d buffers", __FUNCTION__, bufferIdx);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001166 for (uint32_t i = 0; i < bufferIdx; i++) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001167 res = mConsumerInterface->cancelBuffer(mConsumerInterface.get(),
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001168 anwBuffers[i], -1);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001169 if (res != OK) {
1170 ALOGE("%s: Unable to cancel buffer %d after registration",
1171 __FUNCTION__, i);
1172 }
1173 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001174 delete[] anwBuffers;
1175 delete[] buffers;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001176
1177 return res;
1178}
1179
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001180status_t Camera2Device::StreamAdapter::release() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001181 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001182 status_t res;
Eino-Ville Talvala02f84572013-04-23 15:16:57 -07001183 ALOGV("%s: Releasing stream %d (%d x %d, format %d)", __FUNCTION__, mId,
1184 mWidth, mHeight, mFormat);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001185 if (mState >= ALLOCATED) {
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001186 res = mHal2Device->ops->release_stream(mHal2Device, mId);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001187 if (res != OK) {
1188 ALOGE("%s: Unable to release stream %d",
1189 __FUNCTION__, mId);
1190 return res;
1191 }
1192 }
1193 if (mState >= CONNECTED) {
1194 res = native_window_api_disconnect(mConsumerInterface.get(),
1195 NATIVE_WINDOW_API_CAMERA);
Igor Murashkina1e5dcc2012-10-02 15:21:31 -07001196
1197 /* this is not an error. if client calling process dies,
1198 the window will also die and all calls to it will return
1199 DEAD_OBJECT, thus it's already "disconnected" */
1200 if (res == DEAD_OBJECT) {
1201 ALOGW("%s: While disconnecting stream %d from native window, the"
1202 " native window died from under us", __FUNCTION__, mId);
1203 }
1204 else if (res != OK) {
1205 ALOGE("%s: Unable to disconnect stream %d from native window (error %d %s)",
1206 __FUNCTION__, mId, res, strerror(-res));
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001207 return res;
1208 }
1209 }
1210 mId = -1;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001211 mState = RELEASED;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001212 return OK;
1213}
1214
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001215status_t Camera2Device::StreamAdapter::setTransform(int transform) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001216 ATRACE_CALL();
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001217 status_t res;
1218 if (mState < CONNECTED) {
1219 ALOGE("%s: Cannot set transform on unconnected stream", __FUNCTION__);
1220 return INVALID_OPERATION;
1221 }
1222 res = native_window_set_buffers_transform(mConsumerInterface.get(),
1223 transform);
1224 if (res != OK) {
1225 ALOGE("%s: Unable to configure stream transform to %x: %s (%d)",
1226 __FUNCTION__, transform, strerror(-res), res);
1227 }
1228 return res;
1229}
1230
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001231status_t Camera2Device::StreamAdapter::dump(int fd,
Igor Murashkinebe3f692012-10-12 16:56:11 -07001232 const Vector<String16>& /*args*/) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001233 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001234 String8 result = String8::format(" Stream %d: %d x %d, format 0x%x\n",
1235 mId, mWidth, mHeight, mFormat);
Kévin PETIT377b2ec2014-02-03 12:35:36 +00001236 result.appendFormat(" size %zu, usage 0x%x, requested format 0x%x\n",
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001237 mSize, mUsage, mFormatRequested);
1238 result.appendFormat(" total buffers: %d, dequeued buffers: %d\n",
1239 mTotalBuffers, mActiveBuffers);
Kévin PETIT377b2ec2014-02-03 12:35:36 +00001240 result.appendFormat(" frame count: %d, last timestamp %" PRId64 "\n",
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001241 mFrameCount, mLastTimestamp);
1242 write(fd, result.string(), result.size());
1243 return OK;
1244}
1245
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001246const camera2_stream_ops *Camera2Device::StreamAdapter::getStreamOps() {
1247 return static_cast<camera2_stream_ops *>(this);
1248}
1249
1250ANativeWindow* Camera2Device::StreamAdapter::toANW(
1251 const camera2_stream_ops_t *w) {
1252 return static_cast<const StreamAdapter*>(w)->mConsumerInterface.get();
1253}
1254
1255int Camera2Device::StreamAdapter::dequeue_buffer(const camera2_stream_ops_t *w,
1256 buffer_handle_t** buffer) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001257 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001258 int res;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001259 StreamAdapter* stream =
1260 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
1261 if (stream->mState != ACTIVE) {
1262 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001263 return INVALID_OPERATION;
1264 }
1265
1266 ANativeWindow *a = toANW(w);
1267 ANativeWindowBuffer* anb;
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001268 res = native_window_dequeue_buffer_and_wait(a, &anb);
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001269 if (res != OK) {
1270 ALOGE("Stream %d dequeue: Error from native_window: %s (%d)", stream->mId,
1271 strerror(-res), res);
1272 return res;
1273 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001274
1275 *buffer = &(anb->handle);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001276 stream->mActiveBuffers++;
1277
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001278 ALOGVV("Stream %d dequeue: Buffer %p dequeued", stream->mId, (void*)(**buffer));
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001279 return res;
1280}
1281
1282int Camera2Device::StreamAdapter::enqueue_buffer(const camera2_stream_ops_t* w,
1283 int64_t timestamp,
1284 buffer_handle_t* buffer) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001285 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001286 StreamAdapter *stream =
1287 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001288 stream->mFrameCount++;
1289 ALOGVV("Stream %d enqueue: Frame %d (%p) captured at %lld ns",
James Donga289bf62012-09-05 16:46:36 -07001290 stream->mId, stream->mFrameCount, (void*)(*buffer), timestamp);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001291 int state = stream->mState;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001292 if (state != ACTIVE) {
1293 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1294 return INVALID_OPERATION;
1295 }
1296 ANativeWindow *a = toANW(w);
1297 status_t err;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001298
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001299 err = native_window_set_buffers_timestamp(a, timestamp);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001300 if (err != OK) {
1301 ALOGE("%s: Error setting timestamp on native window: %s (%d)",
1302 __FUNCTION__, strerror(-err), err);
1303 return err;
1304 }
1305 err = a->queueBuffer(a,
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001306 container_of(buffer, ANativeWindowBuffer, handle), -1);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001307 if (err != OK) {
1308 ALOGE("%s: Error queueing buffer to native window: %s (%d)",
1309 __FUNCTION__, strerror(-err), err);
James Dong31d377b2012-08-09 17:43:46 -07001310 return err;
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001311 }
James Dong31d377b2012-08-09 17:43:46 -07001312
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001313 stream->mActiveBuffers--;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001314 stream->mLastTimestamp = timestamp;
James Dong31d377b2012-08-09 17:43:46 -07001315 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001316}
1317
1318int Camera2Device::StreamAdapter::cancel_buffer(const camera2_stream_ops_t* w,
1319 buffer_handle_t* buffer) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001320 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001321 StreamAdapter *stream =
1322 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001323 ALOGVV("Stream %d cancel: Buffer %p",
1324 stream->mId, (void*)(*buffer));
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001325 if (stream->mState != ACTIVE) {
1326 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001327 return INVALID_OPERATION;
1328 }
James Dong31d377b2012-08-09 17:43:46 -07001329
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001330 ANativeWindow *a = toANW(w);
James Dong31d377b2012-08-09 17:43:46 -07001331 int err = a->cancelBuffer(a,
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001332 container_of(buffer, ANativeWindowBuffer, handle), -1);
James Dong31d377b2012-08-09 17:43:46 -07001333 if (err != OK) {
1334 ALOGE("%s: Error canceling buffer to native window: %s (%d)",
1335 __FUNCTION__, strerror(-err), err);
1336 return err;
1337 }
1338
1339 stream->mActiveBuffers--;
1340 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001341}
1342
1343int Camera2Device::StreamAdapter::set_crop(const camera2_stream_ops_t* w,
1344 int left, int top, int right, int bottom) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001345 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001346 int state = static_cast<const StreamAdapter*>(w)->mState;
1347 if (state != ACTIVE) {
1348 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1349 return INVALID_OPERATION;
1350 }
1351 ANativeWindow *a = toANW(w);
1352 android_native_rect_t crop = { left, top, right, bottom };
1353 return native_window_set_crop(a, &crop);
1354}
1355
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001356/**
1357 * Camera2Device::ReprocessStreamAdapter
1358 */
1359
1360#ifndef container_of
1361#define container_of(ptr, type, member) \
1362 (type *)((char*)(ptr) - offsetof(type, member))
1363#endif
1364
1365Camera2Device::ReprocessStreamAdapter::ReprocessStreamAdapter(camera2_device_t *d):
1366 mState(RELEASED),
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001367 mHal2Device(d),
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001368 mId(-1),
1369 mWidth(0), mHeight(0), mFormat(0),
1370 mActiveBuffers(0),
1371 mFrameCount(0)
1372{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001373 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001374 camera2_stream_in_ops::acquire_buffer = acquire_buffer;
1375 camera2_stream_in_ops::release_buffer = release_buffer;
1376}
1377
1378Camera2Device::ReprocessStreamAdapter::~ReprocessStreamAdapter() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001379 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001380 if (mState != RELEASED) {
1381 release();
1382 }
1383}
1384
1385status_t Camera2Device::ReprocessStreamAdapter::connectToDevice(
1386 const sp<StreamAdapter> &outputStream) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001387 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001388 status_t res;
1389 ALOGV("%s: E", __FUNCTION__);
1390
1391 if (mState != RELEASED) return INVALID_OPERATION;
1392 if (outputStream == NULL) {
1393 ALOGE("%s: Null base stream passed to reprocess stream adapter",
1394 __FUNCTION__);
1395 return BAD_VALUE;
1396 }
1397
1398 mBaseStream = outputStream;
1399 mWidth = outputStream->getWidth();
1400 mHeight = outputStream->getHeight();
1401 mFormat = outputStream->getFormat();
1402
1403 ALOGV("%s: New reprocess stream parameters %d x %d, format 0x%x",
1404 __FUNCTION__, mWidth, mHeight, mFormat);
1405
1406 // Allocate device-side stream interface
1407
1408 uint32_t id;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001409 res = mHal2Device->ops->allocate_reprocess_stream_from_stream(mHal2Device,
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001410 outputStream->getId(), getStreamOps(),
1411 &id);
1412 if (res != OK) {
1413 ALOGE("%s: Device reprocess stream allocation failed: %s (%d)",
1414 __FUNCTION__, strerror(-res), res);
1415 return res;
1416 }
1417
1418 ALOGV("%s: Allocated reprocess stream id %d based on stream %d",
1419 __FUNCTION__, id, outputStream->getId());
1420
1421 mId = id;
1422
1423 mState = ACTIVE;
1424
1425 return OK;
1426}
1427
1428status_t Camera2Device::ReprocessStreamAdapter::release() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001429 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001430 status_t res;
1431 ALOGV("%s: Releasing stream %d", __FUNCTION__, mId);
1432 if (mState >= ACTIVE) {
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001433 res = mHal2Device->ops->release_reprocess_stream(mHal2Device, mId);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001434 if (res != OK) {
1435 ALOGE("%s: Unable to release stream %d",
1436 __FUNCTION__, mId);
1437 return res;
1438 }
1439 }
1440
1441 List<QueueEntry>::iterator s;
1442 for (s = mQueue.begin(); s != mQueue.end(); s++) {
1443 sp<BufferReleasedListener> listener = s->releaseListener.promote();
1444 if (listener != 0) listener->onBufferReleased(s->handle);
1445 }
1446 for (s = mInFlightQueue.begin(); s != mInFlightQueue.end(); s++) {
1447 sp<BufferReleasedListener> listener = s->releaseListener.promote();
1448 if (listener != 0) listener->onBufferReleased(s->handle);
1449 }
1450 mQueue.clear();
1451 mInFlightQueue.clear();
1452
1453 mState = RELEASED;
1454 return OK;
1455}
1456
1457status_t Camera2Device::ReprocessStreamAdapter::pushIntoStream(
1458 buffer_handle_t *handle, const wp<BufferReleasedListener> &releaseListener) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001459 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001460 // TODO: Some error checking here would be nice
1461 ALOGV("%s: Pushing buffer %p to stream", __FUNCTION__, (void*)(*handle));
1462
1463 QueueEntry entry;
1464 entry.handle = handle;
1465 entry.releaseListener = releaseListener;
1466 mQueue.push_back(entry);
1467 return OK;
1468}
1469
1470status_t Camera2Device::ReprocessStreamAdapter::dump(int fd,
Igor Murashkinebe3f692012-10-12 16:56:11 -07001471 const Vector<String16>& /*args*/) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001472 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001473 String8 result =
1474 String8::format(" Reprocess stream %d: %d x %d, fmt 0x%x\n",
1475 mId, mWidth, mHeight, mFormat);
1476 result.appendFormat(" acquired buffers: %d\n",
1477 mActiveBuffers);
1478 result.appendFormat(" frame count: %d\n",
1479 mFrameCount);
1480 write(fd, result.string(), result.size());
1481 return OK;
1482}
1483
1484const camera2_stream_in_ops *Camera2Device::ReprocessStreamAdapter::getStreamOps() {
1485 return static_cast<camera2_stream_in_ops *>(this);
1486}
1487
1488int Camera2Device::ReprocessStreamAdapter::acquire_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();
Igor Murashkinebe3f692012-10-12 16:56:11 -07001492
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001493 ReprocessStreamAdapter* stream =
1494 const_cast<ReprocessStreamAdapter*>(
1495 static_cast<const ReprocessStreamAdapter*>(w));
1496 if (stream->mState != ACTIVE) {
1497 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
1498 return INVALID_OPERATION;
1499 }
1500
1501 if (stream->mQueue.empty()) {
1502 *buffer = NULL;
1503 return OK;
1504 }
1505
1506 QueueEntry &entry = *(stream->mQueue.begin());
1507
1508 *buffer = entry.handle;
1509
1510 stream->mInFlightQueue.push_back(entry);
1511 stream->mQueue.erase(stream->mQueue.begin());
1512
1513 stream->mActiveBuffers++;
1514
1515 ALOGV("Stream %d acquire: Buffer %p acquired", stream->mId,
1516 (void*)(**buffer));
1517 return OK;
1518}
1519
1520int Camera2Device::ReprocessStreamAdapter::release_buffer(
1521 const camera2_stream_in_ops_t* w,
1522 buffer_handle_t* buffer) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001523 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001524 ReprocessStreamAdapter *stream =
1525 const_cast<ReprocessStreamAdapter*>(
1526 static_cast<const ReprocessStreamAdapter*>(w) );
1527 stream->mFrameCount++;
1528 ALOGV("Reprocess stream %d release: Frame %d (%p)",
1529 stream->mId, stream->mFrameCount, (void*)*buffer);
1530 int state = stream->mState;
1531 if (state != ACTIVE) {
1532 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1533 return INVALID_OPERATION;
1534 }
1535 stream->mActiveBuffers--;
1536
1537 List<QueueEntry>::iterator s;
1538 for (s = stream->mInFlightQueue.begin(); s != stream->mInFlightQueue.end(); s++) {
1539 if ( s->handle == buffer ) break;
1540 }
1541 if (s == stream->mInFlightQueue.end()) {
1542 ALOGE("%s: Can't find buffer %p in in-flight list!", __FUNCTION__,
1543 buffer);
1544 return INVALID_OPERATION;
1545 }
1546
1547 sp<BufferReleasedListener> listener = s->releaseListener.promote();
1548 if (listener != 0) {
1549 listener->onBufferReleased(s->handle);
1550 } else {
1551 ALOGE("%s: Can't free buffer - missing listener", __FUNCTION__);
1552 }
1553 stream->mInFlightQueue.erase(s);
1554
1555 return OK;
1556}
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001557
1558}; // namespace android