blob: d74f9760e25f0dea8db71f4534875e9f7d1ba523 [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"
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -070033#include "CameraService.h"
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070034
35namespace android {
36
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070037Camera2Device::Camera2Device(int id):
38 mId(id),
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -080039 mHal2Device(NULL)
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070040{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -070041 ATRACE_CALL();
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -070042 ALOGV("%s: Created device for camera %d", __FUNCTION__, id);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070043}
44
45Camera2Device::~Camera2Device()
46{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -070047 ATRACE_CALL();
Igor Murashkin8dcdb952012-10-02 16:05:11 -070048 ALOGV("%s: Tearing down for camera id %d", __FUNCTION__, mId);
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -070049 disconnect();
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070050}
51
Igor Murashkin71381052013-03-04 14:53:08 -080052int Camera2Device::getId() const {
53 return mId;
54}
55
Yin-Chia Yehe074a932015-01-30 10:29:02 -080056status_t Camera2Device::initialize(CameraModule *module)
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070057{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -070058 ATRACE_CALL();
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -070059 ALOGV("%s: Initializing device for camera %d", __FUNCTION__, mId);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -080060 if (mHal2Device != NULL) {
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -070061 ALOGE("%s: Already initialized!", __FUNCTION__);
62 return INVALID_OPERATION;
63 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -070064
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070065 status_t res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070066 char name[10];
67 snprintf(name, sizeof(name), "%d", mId);
68
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -070069 camera2_device_t *device;
70
Chien-Yu Chend231fd62015-02-25 16:04:22 -080071 res = module->open(name, 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;
Yin-Chia Yehe074a932015-01-30 10:29:02 -080089 res = module->getCameraInfo(mId, &info);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070090 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 Talvala727d1722015-06-09 13:44:19 -0700243status_t Camera2Device::createStream(sp<Surface> consumer,
Eino-Ville Talvala3d82c0d2015-02-23 15:19:19 -0800244 uint32_t width, uint32_t height, int format,
Yin-Chia Yehb97babb2015-03-12 13:42:44 -0700245 android_dataspace /*dataSpace*/, camera3_stream_rotation_t rotation, int *id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700246 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700247 status_t res;
248 ALOGV("%s: E", __FUNCTION__);
249
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800250 sp<StreamAdapter> stream = new StreamAdapter(mHal2Device);
Zhijun He28c9b6f2014-08-08 12:00:47 -0700251 size_t size = 0;
252 if (format == HAL_PIXEL_FORMAT_BLOB) {
253 size = getJpegBufferSize(width, height);
254 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700255 res = stream->connectToDevice(consumer, width, height, format, size);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700256 if (res != OK) {
257 ALOGE("%s: Camera %d: Unable to create stream (%d x %d, format %x):"
258 "%s (%d)",
259 __FUNCTION__, mId, width, height, format, strerror(-res), res);
260 return res;
261 }
262
263 *id = stream->getId();
264
265 mStreams.push_back(stream);
266 return OK;
267}
268
Zhijun He28c9b6f2014-08-08 12:00:47 -0700269ssize_t Camera2Device::getJpegBufferSize(uint32_t width, uint32_t height) const {
270 // Always give the max jpeg buffer size regardless of the actual jpeg resolution.
271 camera_metadata_ro_entry jpegBufMaxSize = mDeviceInfo.find(ANDROID_JPEG_MAX_SIZE);
272 if (jpegBufMaxSize.count == 0) {
273 ALOGE("%s: Camera %d: Can't find maximum JPEG size in static metadata!", __FUNCTION__, mId);
274 return BAD_VALUE;
275 }
276
277 return jpegBufMaxSize.data.i32[0];
278}
279
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700280status_t Camera2Device::createReprocessStreamFromStream(int outputId, int *id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700281 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700282 status_t res;
283 ALOGV("%s: E", __FUNCTION__);
284
285 bool found = false;
286 StreamList::iterator streamI;
287 for (streamI = mStreams.begin();
288 streamI != mStreams.end(); streamI++) {
289 if ((*streamI)->getId() == outputId) {
290 found = true;
291 break;
292 }
293 }
294 if (!found) {
295 ALOGE("%s: Camera %d: Output stream %d doesn't exist; can't create "
296 "reprocess stream from it!", __FUNCTION__, mId, outputId);
297 return BAD_VALUE;
298 }
299
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800300 sp<ReprocessStreamAdapter> stream = new ReprocessStreamAdapter(mHal2Device);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700301
302 res = stream->connectToDevice((*streamI));
303 if (res != OK) {
304 ALOGE("%s: Camera %d: Unable to create reprocessing stream from "\
305 "stream %d: %s (%d)", __FUNCTION__, mId, outputId,
306 strerror(-res), res);
307 return res;
308 }
309
310 *id = stream->getId();
311
312 mReprocessStreams.push_back(stream);
313 return OK;
314}
315
316
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700317status_t Camera2Device::getStreamInfo(int id,
Eino-Ville Talvalad46a6b92015-05-14 17:26:24 -0700318 uint32_t *width, uint32_t *height,
319 uint32_t *format, android_dataspace *dataSpace) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700320 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700321 ALOGV("%s: E", __FUNCTION__);
322 bool found = false;
323 StreamList::iterator streamI;
324 for (streamI = mStreams.begin();
325 streamI != mStreams.end(); streamI++) {
326 if ((*streamI)->getId() == id) {
327 found = true;
328 break;
329 }
330 }
331 if (!found) {
332 ALOGE("%s: Camera %d: Stream %d does not exist",
333 __FUNCTION__, mId, id);
334 return BAD_VALUE;
335 }
336
337 if (width) *width = (*streamI)->getWidth();
338 if (height) *height = (*streamI)->getHeight();
339 if (format) *format = (*streamI)->getFormat();
Eino-Ville Talvalad46a6b92015-05-14 17:26:24 -0700340 if (dataSpace) *dataSpace = HAL_DATASPACE_UNKNOWN;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700341
342 return OK;
343}
344
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -0700345status_t Camera2Device::setStreamTransform(int id,
346 int transform) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700347 ATRACE_CALL();
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -0700348 ALOGV("%s: E", __FUNCTION__);
349 bool found = false;
350 StreamList::iterator streamI;
351 for (streamI = mStreams.begin();
352 streamI != mStreams.end(); streamI++) {
353 if ((*streamI)->getId() == id) {
354 found = true;
355 break;
356 }
357 }
358 if (!found) {
359 ALOGE("%s: Camera %d: Stream %d does not exist",
360 __FUNCTION__, mId, id);
361 return BAD_VALUE;
362 }
363
364 return (*streamI)->setTransform(transform);
365}
366
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700367status_t Camera2Device::deleteStream(int id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700368 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700369 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700370 bool found = false;
371 for (StreamList::iterator streamI = mStreams.begin();
372 streamI != mStreams.end(); streamI++) {
373 if ((*streamI)->getId() == id) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700374 status_t res = (*streamI)->release();
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700375 if (res != OK) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700376 ALOGE("%s: Unable to release stream %d from HAL device: "
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700377 "%s (%d)", __FUNCTION__, id, strerror(-res), res);
378 return res;
379 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700380 mStreams.erase(streamI);
381 found = true;
382 break;
383 }
384 }
385 if (!found) {
386 ALOGE("%s: Camera %d: Unable to find stream %d to delete",
387 __FUNCTION__, mId, id);
388 return BAD_VALUE;
389 }
390 return OK;
391}
392
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700393status_t Camera2Device::deleteReprocessStream(int id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700394 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700395 ALOGV("%s: E", __FUNCTION__);
396 bool found = false;
397 for (ReprocessStreamList::iterator streamI = mReprocessStreams.begin();
398 streamI != mReprocessStreams.end(); streamI++) {
399 if ((*streamI)->getId() == id) {
400 status_t res = (*streamI)->release();
401 if (res != OK) {
402 ALOGE("%s: Unable to release reprocess stream %d from "
403 "HAL device: %s (%d)", __FUNCTION__, id,
404 strerror(-res), res);
405 return res;
406 }
407 mReprocessStreams.erase(streamI);
408 found = true;
409 break;
410 }
411 }
412 if (!found) {
413 ALOGE("%s: Camera %d: Unable to find stream %d to delete",
414 __FUNCTION__, mId, id);
415 return BAD_VALUE;
416 }
417 return OK;
418}
419
Zhijun He1fa89992015-06-01 15:44:31 -0700420status_t Camera2Device::configureStreams(bool isConstrainedHighSpeed) {
Igor Murashkine2d167e2014-08-19 16:19:59 -0700421 ATRACE_CALL();
422 ALOGV("%s: E", __FUNCTION__);
423
424 /**
425 * HAL2 devices do not need to configure streams;
426 * streams are created on the fly.
427 */
428 ALOGW("%s: No-op for HAL2 devices", __FUNCTION__);
429
430 return OK;
431}
432
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700433
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700434status_t Camera2Device::createDefaultRequest(int templateId,
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700435 CameraMetadata *request) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700436 ATRACE_CALL();
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700437 status_t err;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700438 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700439 camera_metadata_t *rawRequest;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800440 err = mHal2Device->ops->construct_default_request(
441 mHal2Device, templateId, &rawRequest);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700442 request->acquire(rawRequest);
443 return err;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700444}
445
446status_t Camera2Device::waitUntilDrained() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700447 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700448 static const uint32_t kSleepTime = 50000; // 50 ms
449 static const uint32_t kMaxSleepTime = 10000000; // 10 s
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700450 ALOGV("%s: Camera %d: Starting wait", __FUNCTION__, mId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700451 if (mRequestQueue.getBufferCount() ==
452 CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS) return INVALID_OPERATION;
453
454 // TODO: Set up notifications from HAL, instead of sleeping here
455 uint32_t totalTime = 0;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800456 while (mHal2Device->ops->get_in_progress_count(mHal2Device) > 0) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700457 usleep(kSleepTime);
458 totalTime += kSleepTime;
459 if (totalTime > kMaxSleepTime) {
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700460 ALOGE("%s: Waited %d us, %d requests still in flight", __FUNCTION__,
Alex Rayf0eeb532013-03-17 03:23:18 -0700461 totalTime, mHal2Device->ops->get_in_progress_count(mHal2Device));
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700462 return TIMED_OUT;
463 }
464 }
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700465 ALOGV("%s: Camera %d: HAL is idle", __FUNCTION__, mId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700466 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700467}
468
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700469status_t Camera2Device::setNotifyCallback(NotificationListener *listener) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700470 ATRACE_CALL();
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700471 status_t res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800472 res = mHal2Device->ops->set_notify_callback(mHal2Device, notificationCallback,
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700473 reinterpret_cast<void*>(listener) );
474 if (res != OK) {
475 ALOGE("%s: Unable to set notification callback!", __FUNCTION__);
476 }
477 return res;
478}
479
Eino-Ville Talvala46910bd2013-07-18 19:15:17 -0700480bool Camera2Device::willNotify3A() {
481 return true;
482}
483
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700484void Camera2Device::notificationCallback(int32_t msg_type,
485 int32_t ext1,
486 int32_t ext2,
487 int32_t ext3,
488 void *user) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700489 ATRACE_CALL();
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700490 NotificationListener *listener = reinterpret_cast<NotificationListener*>(user);
491 ALOGV("%s: Notification %d, arguments %d, %d, %d", __FUNCTION__, msg_type,
492 ext1, ext2, ext3);
493 if (listener != NULL) {
494 switch (msg_type) {
495 case CAMERA2_MSG_ERROR:
Jianing Weicb0652e2014-03-12 18:29:36 -0700496 // TODO: This needs to be fixed. ext2 and ext3 need to be considered.
497 listener->notifyError(
498 ((ext1 == CAMERA2_MSG_ERROR_DEVICE)
499 || (ext1 == CAMERA2_MSG_ERROR_HARDWARE)) ?
500 ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE :
501 ICameraDeviceCallbacks::ERROR_CAMERA_SERVICE,
502 CaptureResultExtras());
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700503 break;
504 case CAMERA2_MSG_SHUTTER: {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700505 // TODO: Only needed for camera2 API, which is unsupported
506 // by HAL2 directly.
507 // nsecs_t timestamp = (nsecs_t)ext2 | ((nsecs_t)(ext3) << 32 );
508 // listener->notifyShutter(requestId, timestamp);
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700509 break;
510 }
511 case CAMERA2_MSG_AUTOFOCUS:
512 listener->notifyAutoFocus(ext1, ext2);
513 break;
514 case CAMERA2_MSG_AUTOEXPOSURE:
515 listener->notifyAutoExposure(ext1, ext2);
516 break;
517 case CAMERA2_MSG_AUTOWB:
518 listener->notifyAutoWhitebalance(ext1, ext2);
519 break;
520 default:
521 ALOGE("%s: Unknown notification %d (arguments %d, %d, %d)!",
522 __FUNCTION__, msg_type, ext1, ext2, ext3);
523 }
524 }
525}
526
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -0700527status_t Camera2Device::waitForNextFrame(nsecs_t timeout) {
528 return mFrameQueue.waitForBuffer(timeout);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700529}
530
Jianing Weicb0652e2014-03-12 18:29:36 -0700531status_t Camera2Device::getNextResult(CaptureResult *result) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700532 ATRACE_CALL();
Jianing Weicb0652e2014-03-12 18:29:36 -0700533 ALOGV("%s: get CaptureResult", __FUNCTION__);
534 if (result == NULL) {
535 ALOGE("%s: result pointer is NULL", __FUNCTION__);
536 return BAD_VALUE;
537 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700538 status_t res;
539 camera_metadata_t *rawFrame;
540 res = mFrameQueue.dequeue(&rawFrame);
Jianing Weicb0652e2014-03-12 18:29:36 -0700541 if (rawFrame == NULL) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700542 return NOT_ENOUGH_DATA;
543 } else if (res == OK) {
Jianing Weicb0652e2014-03-12 18:29:36 -0700544 result->mMetadata.acquire(rawFrame);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700545 }
Jianing Weicb0652e2014-03-12 18:29:36 -0700546
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700547 return res;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700548}
549
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700550status_t Camera2Device::triggerAutofocus(uint32_t id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700551 ATRACE_CALL();
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700552 status_t res;
553 ALOGV("%s: Triggering autofocus, id %d", __FUNCTION__, id);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800554 res = mHal2Device->ops->trigger_action(mHal2Device,
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700555 CAMERA2_TRIGGER_AUTOFOCUS, id, 0);
556 if (res != OK) {
557 ALOGE("%s: Error triggering autofocus (id %d)",
558 __FUNCTION__, id);
559 }
560 return res;
561}
562
563status_t Camera2Device::triggerCancelAutofocus(uint32_t id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700564 ATRACE_CALL();
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700565 status_t res;
566 ALOGV("%s: Canceling autofocus, id %d", __FUNCTION__, id);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800567 res = mHal2Device->ops->trigger_action(mHal2Device,
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700568 CAMERA2_TRIGGER_CANCEL_AUTOFOCUS, id, 0);
569 if (res != OK) {
570 ALOGE("%s: Error canceling autofocus (id %d)",
571 __FUNCTION__, id);
572 }
573 return res;
574}
575
576status_t Camera2Device::triggerPrecaptureMetering(uint32_t id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700577 ATRACE_CALL();
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700578 status_t res;
579 ALOGV("%s: Triggering precapture metering, id %d", __FUNCTION__, id);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800580 res = mHal2Device->ops->trigger_action(mHal2Device,
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700581 CAMERA2_TRIGGER_PRECAPTURE_METERING, id, 0);
582 if (res != OK) {
583 ALOGE("%s: Error triggering precapture metering (id %d)",
584 __FUNCTION__, id);
585 }
586 return res;
587}
588
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700589status_t Camera2Device::pushReprocessBuffer(int reprocessStreamId,
590 buffer_handle_t *buffer, wp<BufferReleasedListener> listener) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700591 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700592 ALOGV("%s: E", __FUNCTION__);
593 bool found = false;
594 status_t res = OK;
595 for (ReprocessStreamList::iterator streamI = mReprocessStreams.begin();
596 streamI != mReprocessStreams.end(); streamI++) {
597 if ((*streamI)->getId() == reprocessStreamId) {
598 res = (*streamI)->pushIntoStream(buffer, listener);
599 if (res != OK) {
600 ALOGE("%s: Unable to push buffer to reprocess stream %d: %s (%d)",
601 __FUNCTION__, reprocessStreamId, strerror(-res), res);
602 return res;
603 }
604 found = true;
605 break;
606 }
607 }
608 if (!found) {
609 ALOGE("%s: Camera %d: Unable to find reprocess stream %d",
610 __FUNCTION__, mId, reprocessStreamId);
611 res = BAD_VALUE;
612 }
613 return res;
614}
615
Jianing Weicb0652e2014-03-12 18:29:36 -0700616status_t Camera2Device::flush(int64_t* /*lastFrameNumber*/) {
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -0700617 ATRACE_CALL();
618
619 mRequestQueue.clear();
620 return waitUntilDrained();
621}
622
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700623status_t Camera2Device::prepare(int streamId) {
624 ATRACE_CALL();
625 ALOGE("%s: Camera %d: unimplemented", __FUNCTION__, mId);
626 return NO_INIT;
627}
628
Eino-Ville Talvalab25e3c82015-07-15 16:04:27 -0700629status_t Camera2Device::tearDown(int streamId) {
630 ATRACE_CALL();
631 ALOGE("%s: Camera %d: unimplemented", __FUNCTION__, mId);
632 return NO_INIT;
633}
634
Ruben Brunkc78ac262015-08-13 17:58:46 -0700635status_t Camera2Device::prepare(int maxCount, int streamId) {
636 ATRACE_CALL();
637 ALOGE("%s: Camera %d: unimplemented", __FUNCTION__, mId);
638 return NO_INIT;
639}
640
Zhijun He204e3292014-07-14 17:09:23 -0700641uint32_t Camera2Device::getDeviceVersion() {
642 ATRACE_CALL();
643 return mDeviceVersion;
644}
645
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700646/**
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700647 * Camera2Device::MetadataQueue
648 */
649
650Camera2Device::MetadataQueue::MetadataQueue():
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800651 mHal2Device(NULL),
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700652 mFrameCount(0),
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700653 mLatestRequestId(0),
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700654 mCount(0),
655 mStreamSlotCount(0),
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -0700656 mSignalConsumer(true)
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700657{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700658 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700659 camera2_request_queue_src_ops::dequeue_request = consumer_dequeue;
660 camera2_request_queue_src_ops::request_count = consumer_buffer_count;
661 camera2_request_queue_src_ops::free_request = consumer_free;
662
663 camera2_frame_queue_dst_ops::dequeue_frame = producer_dequeue;
664 camera2_frame_queue_dst_ops::cancel_frame = producer_cancel;
665 camera2_frame_queue_dst_ops::enqueue_frame = producer_enqueue;
666}
667
668Camera2Device::MetadataQueue::~MetadataQueue() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700669 ATRACE_CALL();
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -0700670 clear();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700671}
672
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700673// Connect to camera2 HAL as consumer (input requests/reprocessing)
674status_t Camera2Device::MetadataQueue::setConsumerDevice(camera2_device_t *d) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700675 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700676 status_t res;
677 res = d->ops->set_request_queue_src_ops(d,
678 this);
679 if (res != OK) return res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800680 mHal2Device = d;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700681 return OK;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700682}
683
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700684status_t Camera2Device::MetadataQueue::setProducerDevice(camera2_device_t *d) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700685 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700686 status_t res;
687 res = d->ops->set_frame_queue_dst_ops(d,
688 this);
689 return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700690}
691
692// Real interfaces
693status_t Camera2Device::MetadataQueue::enqueue(camera_metadata_t *buf) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700694 ATRACE_CALL();
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700695 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700696 Mutex::Autolock l(mMutex);
697
698 mCount++;
699 mEntries.push_back(buf);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700700
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700701 return signalConsumerLocked();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700702}
703
704int Camera2Device::MetadataQueue::getBufferCount() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700705 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700706 Mutex::Autolock l(mMutex);
707 if (mStreamSlotCount > 0) {
708 return CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS;
709 }
710 return mCount;
711}
712
713status_t Camera2Device::MetadataQueue::dequeue(camera_metadata_t **buf,
714 bool incrementCount)
715{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700716 ATRACE_CALL();
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700717 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700718 status_t res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700719 Mutex::Autolock l(mMutex);
720
721 if (mCount == 0) {
722 if (mStreamSlotCount == 0) {
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700723 ALOGVV("%s: Empty", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700724 *buf = NULL;
725 mSignalConsumer = true;
726 return OK;
727 }
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700728 ALOGVV("%s: Streaming %d frames to queue", __FUNCTION__,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700729 mStreamSlotCount);
730
731 for (List<camera_metadata_t*>::iterator slotEntry = mStreamSlot.begin();
732 slotEntry != mStreamSlot.end();
733 slotEntry++ ) {
734 size_t entries = get_camera_metadata_entry_count(*slotEntry);
735 size_t dataBytes = get_camera_metadata_data_count(*slotEntry);
736
737 camera_metadata_t *copy =
738 allocate_camera_metadata(entries, dataBytes);
739 append_camera_metadata(copy, *slotEntry);
740 mEntries.push_back(copy);
741 }
742 mCount = mStreamSlotCount;
743 }
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700744 ALOGVV("MetadataQueue: deque (%d buffers)", mCount);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700745 camera_metadata_t *b = *(mEntries.begin());
746 mEntries.erase(mEntries.begin());
747
748 if (incrementCount) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700749 ATRACE_INT("cam2_request", mFrameCount);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700750 camera_metadata_entry_t frameCount;
751 res = find_camera_metadata_entry(b,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700752 ANDROID_REQUEST_FRAME_COUNT,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700753 &frameCount);
754 if (res != OK) {
755 ALOGE("%s: Unable to add frame count: %s (%d)",
756 __FUNCTION__, strerror(-res), res);
757 } else {
758 *frameCount.data.i32 = mFrameCount;
759 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700760 mFrameCount++;
761 }
762
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700763 // Check for request ID, and if present, signal waiters.
764 camera_metadata_entry_t requestId;
765 res = find_camera_metadata_entry(b,
766 ANDROID_REQUEST_ID,
767 &requestId);
768 if (res == OK) {
769 mLatestRequestId = requestId.data.i32[0];
770 mNewRequestId.signal();
771 }
772
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700773 *buf = b;
774 mCount--;
775
776 return OK;
777}
778
779status_t Camera2Device::MetadataQueue::waitForBuffer(nsecs_t timeout)
780{
781 Mutex::Autolock l(mMutex);
782 status_t res;
783 while (mCount == 0) {
784 res = notEmpty.waitRelative(mMutex,timeout);
785 if (res != OK) return res;
786 }
787 return OK;
788}
789
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700790status_t Camera2Device::MetadataQueue::waitForDequeue(int32_t id,
791 nsecs_t timeout) {
792 Mutex::Autolock l(mMutex);
793 status_t res;
794 while (mLatestRequestId != id) {
795 nsecs_t startTime = systemTime();
796
797 res = mNewRequestId.waitRelative(mMutex, timeout);
798 if (res != OK) return res;
799
800 timeout -= (systemTime() - startTime);
801 }
802
803 return OK;
804}
805
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700806status_t Camera2Device::MetadataQueue::setStreamSlot(camera_metadata_t *buf)
807{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700808 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700809 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700810 Mutex::Autolock l(mMutex);
811 if (buf == NULL) {
812 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
813 mStreamSlotCount = 0;
814 return OK;
815 }
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700816
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700817 if (mStreamSlotCount > 1) {
818 List<camera_metadata_t*>::iterator deleter = ++mStreamSlot.begin();
819 freeBuffers(++mStreamSlot.begin(), mStreamSlot.end());
820 mStreamSlotCount = 1;
821 }
822 if (mStreamSlotCount == 1) {
823 free_camera_metadata( *(mStreamSlot.begin()) );
Chien-Yu Chen80de5dc2014-11-07 17:45:00 -0800824 *(mStreamSlot.begin()) = buf;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700825 } else {
Chien-Yu Chen80de5dc2014-11-07 17:45:00 -0800826 mStreamSlot.push_front(buf);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700827 mStreamSlotCount = 1;
828 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700829 return signalConsumerLocked();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700830}
831
832status_t Camera2Device::MetadataQueue::setStreamSlot(
833 const List<camera_metadata_t*> &bufs)
834{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700835 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700836 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700837 Mutex::Autolock l(mMutex);
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700838
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700839 if (mStreamSlotCount > 0) {
840 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
841 }
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700842 mStreamSlotCount = 0;
843 for (List<camera_metadata_t*>::const_iterator r = bufs.begin();
844 r != bufs.end(); r++) {
Chien-Yu Chen80de5dc2014-11-07 17:45:00 -0800845 mStreamSlot.push_back(*r);
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700846 mStreamSlotCount++;
847 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700848 return signalConsumerLocked();
849}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700850
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -0700851status_t Camera2Device::MetadataQueue::clear()
852{
853 ATRACE_CALL();
854 ALOGV("%s: E", __FUNCTION__);
855
856 Mutex::Autolock l(mMutex);
857
858 // Clear streaming slot
859 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
860 mStreamSlotCount = 0;
861
862 // Clear request queue
863 freeBuffers(mEntries.begin(), mEntries.end());
864 mCount = 0;
865 return OK;
866}
867
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700868status_t Camera2Device::MetadataQueue::dump(int fd,
Igor Murashkinebe3f692012-10-12 16:56:11 -0700869 const Vector<String16>& /*args*/) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700870 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700871 String8 result;
872 status_t notLocked;
873 notLocked = mMutex.tryLock();
874 if (notLocked) {
875 result.append(" (Unable to lock queue mutex)\n");
876 }
877 result.appendFormat(" Current frame number: %d\n", mFrameCount);
878 if (mStreamSlotCount == 0) {
879 result.append(" Stream slot: Empty\n");
880 write(fd, result.string(), result.size());
881 } else {
Kévin PETIT377b2ec2014-02-03 12:35:36 +0000882 result.appendFormat(" Stream slot: %zu entries\n",
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700883 mStreamSlot.size());
884 int i = 0;
885 for (List<camera_metadata_t*>::iterator r = mStreamSlot.begin();
886 r != mStreamSlot.end(); r++) {
887 result = String8::format(" Stream slot buffer %d:\n", i);
888 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700889 dump_indented_camera_metadata(*r, fd, 2, 10);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700890 i++;
891 }
892 }
893 if (mEntries.size() == 0) {
894 result = " Main queue is empty\n";
895 write(fd, result.string(), result.size());
896 } else {
Kévin PETIT377b2ec2014-02-03 12:35:36 +0000897 result = String8::format(" Main queue has %zu entries:\n",
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700898 mEntries.size());
899 int i = 0;
900 for (List<camera_metadata_t*>::iterator r = mEntries.begin();
901 r != mEntries.end(); r++) {
902 result = String8::format(" Queue entry %d:\n", i);
903 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700904 dump_indented_camera_metadata(*r, fd, 2, 10);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700905 i++;
906 }
907 }
908
909 if (notLocked == 0) {
910 mMutex.unlock();
911 }
912
913 return OK;
914}
915
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700916status_t Camera2Device::MetadataQueue::signalConsumerLocked() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700917 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700918 status_t res = OK;
919 notEmpty.signal();
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800920 if (mSignalConsumer && mHal2Device != NULL) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700921 mSignalConsumer = false;
922
923 mMutex.unlock();
924 ALOGV("%s: Signaling consumer", __FUNCTION__);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800925 res = mHal2Device->ops->notify_request_queue_not_empty(mHal2Device);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700926 mMutex.lock();
927 }
928 return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700929}
930
931status_t Camera2Device::MetadataQueue::freeBuffers(
932 List<camera_metadata_t*>::iterator start,
933 List<camera_metadata_t*>::iterator end)
934{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700935 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700936 while (start != end) {
937 free_camera_metadata(*start);
938 start = mStreamSlot.erase(start);
939 }
940 return OK;
941}
942
943Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
944 const camera2_request_queue_src_ops_t *q)
945{
946 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
947 return const_cast<MetadataQueue*>(cmq);
948}
949
950Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
951 const camera2_frame_queue_dst_ops_t *q)
952{
953 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
954 return const_cast<MetadataQueue*>(cmq);
955}
956
957int Camera2Device::MetadataQueue::consumer_buffer_count(
958 const camera2_request_queue_src_ops_t *q)
959{
960 MetadataQueue *queue = getInstance(q);
961 return queue->getBufferCount();
962}
963
964int Camera2Device::MetadataQueue::consumer_dequeue(
965 const camera2_request_queue_src_ops_t *q,
966 camera_metadata_t **buffer)
967{
968 MetadataQueue *queue = getInstance(q);
969 return queue->dequeue(buffer, true);
970}
971
972int Camera2Device::MetadataQueue::consumer_free(
973 const camera2_request_queue_src_ops_t *q,
974 camera_metadata_t *old_buffer)
975{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700976 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700977 MetadataQueue *queue = getInstance(q);
Igor Murashkinebe3f692012-10-12 16:56:11 -0700978 (void)queue;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700979 free_camera_metadata(old_buffer);
980 return OK;
981}
982
983int Camera2Device::MetadataQueue::producer_dequeue(
Igor Murashkinebe3f692012-10-12 16:56:11 -0700984 const camera2_frame_queue_dst_ops_t * /*q*/,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700985 size_t entries, size_t bytes,
986 camera_metadata_t **buffer)
987{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700988 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700989 camera_metadata_t *new_buffer =
990 allocate_camera_metadata(entries, bytes);
991 if (new_buffer == NULL) return NO_MEMORY;
992 *buffer = new_buffer;
993 return OK;
994}
995
996int Camera2Device::MetadataQueue::producer_cancel(
Igor Murashkinebe3f692012-10-12 16:56:11 -0700997 const camera2_frame_queue_dst_ops_t * /*q*/,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700998 camera_metadata_t *old_buffer)
999{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001000 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -07001001 free_camera_metadata(old_buffer);
1002 return OK;
1003}
1004
1005int Camera2Device::MetadataQueue::producer_enqueue(
1006 const camera2_frame_queue_dst_ops_t *q,
1007 camera_metadata_t *filled_buffer)
1008{
1009 MetadataQueue *queue = getInstance(q);
1010 return queue->enqueue(filled_buffer);
1011}
1012
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001013/**
1014 * Camera2Device::StreamAdapter
1015 */
1016
1017#ifndef container_of
1018#define container_of(ptr, type, member) \
1019 (type *)((char*)(ptr) - offsetof(type, member))
1020#endif
1021
1022Camera2Device::StreamAdapter::StreamAdapter(camera2_device_t *d):
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001023 mState(RELEASED),
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001024 mHal2Device(d),
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001025 mId(-1),
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001026 mWidth(0), mHeight(0), mFormat(0), mSize(0), mUsage(0),
1027 mMaxProducerBuffers(0), mMaxConsumerBuffers(0),
1028 mTotalBuffers(0),
1029 mFormatRequested(0),
1030 mActiveBuffers(0),
1031 mFrameCount(0),
1032 mLastTimestamp(0)
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001033{
1034 camera2_stream_ops::dequeue_buffer = dequeue_buffer;
1035 camera2_stream_ops::enqueue_buffer = enqueue_buffer;
1036 camera2_stream_ops::cancel_buffer = cancel_buffer;
1037 camera2_stream_ops::set_crop = set_crop;
1038}
1039
1040Camera2Device::StreamAdapter::~StreamAdapter() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001041 ATRACE_CALL();
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001042 if (mState != RELEASED) {
1043 release();
1044 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001045}
1046
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001047status_t Camera2Device::StreamAdapter::connectToDevice(
1048 sp<ANativeWindow> consumer,
1049 uint32_t width, uint32_t height, int format, size_t size) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001050 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001051 status_t res;
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -07001052 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001053
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001054 if (mState != RELEASED) return INVALID_OPERATION;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001055 if (consumer == NULL) {
1056 ALOGE("%s: Null consumer passed to stream adapter", __FUNCTION__);
1057 return BAD_VALUE;
1058 }
1059
Colin Crosse5729fa2014-03-21 15:04:25 -07001060 ALOGV("%s: New stream parameters %d x %d, format 0x%x, size %zu",
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001061 __FUNCTION__, width, height, format, size);
1062
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001063 mConsumerInterface = consumer;
1064 mWidth = width;
1065 mHeight = height;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001066 mSize = (format == HAL_PIXEL_FORMAT_BLOB) ? size : 0;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001067 mFormatRequested = format;
1068
1069 // Allocate device-side stream interface
1070
1071 uint32_t id;
1072 uint32_t formatActual;
1073 uint32_t usage;
1074 uint32_t maxBuffers = 2;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001075 res = mHal2Device->ops->allocate_stream(mHal2Device,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001076 mWidth, mHeight, mFormatRequested, getStreamOps(),
1077 &id, &formatActual, &usage, &maxBuffers);
1078 if (res != OK) {
1079 ALOGE("%s: Device stream allocation failed: %s (%d)",
1080 __FUNCTION__, strerror(-res), res);
1081 return res;
1082 }
1083
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001084 ALOGV("%s: Allocated stream id %d, actual format 0x%x, "
1085 "usage 0x%x, producer wants %d buffers", __FUNCTION__,
1086 id, formatActual, usage, maxBuffers);
1087
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001088 mId = id;
1089 mFormat = formatActual;
1090 mUsage = usage;
1091 mMaxProducerBuffers = maxBuffers;
1092
1093 mState = ALLOCATED;
1094
1095 // Configure consumer-side ANativeWindow interface
1096 res = native_window_api_connect(mConsumerInterface.get(),
1097 NATIVE_WINDOW_API_CAMERA);
1098 if (res != OK) {
1099 ALOGE("%s: Unable to connect to native window for stream %d",
1100 __FUNCTION__, mId);
1101
1102 return res;
1103 }
1104
1105 mState = CONNECTED;
1106
1107 res = native_window_set_usage(mConsumerInterface.get(), mUsage);
1108 if (res != OK) {
1109 ALOGE("%s: Unable to configure usage %08x for stream %d",
1110 __FUNCTION__, mUsage, mId);
1111 return res;
1112 }
1113
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001114 res = native_window_set_scaling_mode(mConsumerInterface.get(),
1115 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
1116 if (res != OK) {
1117 ALOGE("%s: Unable to configure stream scaling: %s (%d)",
1118 __FUNCTION__, strerror(-res), res);
1119 return res;
1120 }
1121
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001122 res = setTransform(0);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001123 if (res != OK) {
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001124 return res;
1125 }
1126
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001127 if (mFormat == HAL_PIXEL_FORMAT_BLOB) {
Eino-Ville Talvala7d70c5e2014-07-24 18:10:23 -07001128 res = native_window_set_buffers_dimensions(mConsumerInterface.get(),
1129 mSize, 1);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001130 if (res != OK) {
Eino-Ville Talvala7d70c5e2014-07-24 18:10:23 -07001131 ALOGE("%s: Unable to configure compressed stream buffer dimensions"
Colin Crosse5729fa2014-03-21 15:04:25 -07001132 " %d x %d, size %zu for stream %d",
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001133 __FUNCTION__, mWidth, mHeight, mSize, mId);
1134 return res;
1135 }
1136 } else {
Eino-Ville Talvala7d70c5e2014-07-24 18:10:23 -07001137 res = native_window_set_buffers_dimensions(mConsumerInterface.get(),
1138 mWidth, mHeight);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001139 if (res != OK) {
Eino-Ville Talvala7d70c5e2014-07-24 18:10:23 -07001140 ALOGE("%s: Unable to configure stream buffer dimensions"
1141 " %d x %d for stream %d",
1142 __FUNCTION__, mWidth, mHeight, mId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001143 return res;
1144 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001145 }
1146
Eino-Ville Talvala7d70c5e2014-07-24 18:10:23 -07001147 res = native_window_set_buffers_format(mConsumerInterface.get(), mFormat);
1148 if (res != OK) {
1149 ALOGE("%s: Unable to configure stream buffer format"
1150 " %#x for stream %d",
1151 __FUNCTION__, mFormat, mId);
1152 return res;
1153 }
1154
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001155 int maxConsumerBuffers;
1156 res = mConsumerInterface->query(mConsumerInterface.get(),
1157 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &maxConsumerBuffers);
1158 if (res != OK) {
1159 ALOGE("%s: Unable to query consumer undequeued"
1160 " buffer count for stream %d", __FUNCTION__, mId);
1161 return res;
1162 }
1163 mMaxConsumerBuffers = maxConsumerBuffers;
1164
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001165 ALOGV("%s: Consumer wants %d buffers", __FUNCTION__,
1166 mMaxConsumerBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001167
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001168 mTotalBuffers = mMaxConsumerBuffers + mMaxProducerBuffers;
1169 mActiveBuffers = 0;
1170 mFrameCount = 0;
1171 mLastTimestamp = 0;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001172
1173 res = native_window_set_buffer_count(mConsumerInterface.get(),
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001174 mTotalBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001175 if (res != OK) {
1176 ALOGE("%s: Unable to set buffer count for stream %d",
1177 __FUNCTION__, mId);
1178 return res;
1179 }
1180
1181 // Register allocated buffers with HAL device
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001182 buffer_handle_t *buffers = new buffer_handle_t[mTotalBuffers];
1183 ANativeWindowBuffer **anwBuffers = new ANativeWindowBuffer*[mTotalBuffers];
1184 uint32_t bufferIdx = 0;
1185 for (; bufferIdx < mTotalBuffers; bufferIdx++) {
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001186 res = native_window_dequeue_buffer_and_wait(mConsumerInterface.get(),
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001187 &anwBuffers[bufferIdx]);
1188 if (res != OK) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001189 ALOGE("%s: Unable to dequeue buffer %d for initial registration for "
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001190 "stream %d", __FUNCTION__, bufferIdx, mId);
1191 goto cleanUpBuffers;
1192 }
1193
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001194 buffers[bufferIdx] = anwBuffers[bufferIdx]->handle;
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001195 ALOGV("%s: Buffer %p allocated", __FUNCTION__, (void*)buffers[bufferIdx]);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001196 }
1197
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001198 ALOGV("%s: Registering %d buffers with camera HAL", __FUNCTION__, mTotalBuffers);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001199 res = mHal2Device->ops->register_stream_buffers(mHal2Device,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001200 mId,
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001201 mTotalBuffers,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001202 buffers);
1203 if (res != OK) {
1204 ALOGE("%s: Unable to register buffers with HAL device for stream %d",
1205 __FUNCTION__, mId);
1206 } else {
1207 mState = ACTIVE;
1208 }
1209
1210cleanUpBuffers:
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001211 ALOGV("%s: Cleaning up %d buffers", __FUNCTION__, bufferIdx);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001212 for (uint32_t i = 0; i < bufferIdx; i++) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001213 res = mConsumerInterface->cancelBuffer(mConsumerInterface.get(),
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001214 anwBuffers[i], -1);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001215 if (res != OK) {
1216 ALOGE("%s: Unable to cancel buffer %d after registration",
1217 __FUNCTION__, i);
1218 }
1219 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001220 delete[] anwBuffers;
1221 delete[] buffers;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001222
1223 return res;
1224}
1225
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001226status_t Camera2Device::StreamAdapter::release() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001227 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001228 status_t res;
Eino-Ville Talvala02f84572013-04-23 15:16:57 -07001229 ALOGV("%s: Releasing stream %d (%d x %d, format %d)", __FUNCTION__, mId,
1230 mWidth, mHeight, mFormat);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001231 if (mState >= ALLOCATED) {
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001232 res = mHal2Device->ops->release_stream(mHal2Device, mId);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001233 if (res != OK) {
1234 ALOGE("%s: Unable to release stream %d",
1235 __FUNCTION__, mId);
1236 return res;
1237 }
1238 }
1239 if (mState >= CONNECTED) {
1240 res = native_window_api_disconnect(mConsumerInterface.get(),
1241 NATIVE_WINDOW_API_CAMERA);
Igor Murashkina1e5dcc2012-10-02 15:21:31 -07001242
1243 /* this is not an error. if client calling process dies,
1244 the window will also die and all calls to it will return
1245 DEAD_OBJECT, thus it's already "disconnected" */
1246 if (res == DEAD_OBJECT) {
1247 ALOGW("%s: While disconnecting stream %d from native window, the"
1248 " native window died from under us", __FUNCTION__, mId);
1249 }
1250 else if (res != OK) {
1251 ALOGE("%s: Unable to disconnect stream %d from native window (error %d %s)",
1252 __FUNCTION__, mId, res, strerror(-res));
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001253 return res;
1254 }
1255 }
1256 mId = -1;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001257 mState = RELEASED;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001258 return OK;
1259}
1260
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001261status_t Camera2Device::StreamAdapter::setTransform(int transform) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001262 ATRACE_CALL();
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001263 status_t res;
1264 if (mState < CONNECTED) {
1265 ALOGE("%s: Cannot set transform on unconnected stream", __FUNCTION__);
1266 return INVALID_OPERATION;
1267 }
1268 res = native_window_set_buffers_transform(mConsumerInterface.get(),
1269 transform);
1270 if (res != OK) {
1271 ALOGE("%s: Unable to configure stream transform to %x: %s (%d)",
1272 __FUNCTION__, transform, strerror(-res), res);
1273 }
1274 return res;
1275}
1276
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001277status_t Camera2Device::StreamAdapter::dump(int fd,
Igor Murashkinebe3f692012-10-12 16:56:11 -07001278 const Vector<String16>& /*args*/) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001279 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001280 String8 result = String8::format(" Stream %d: %d x %d, format 0x%x\n",
1281 mId, mWidth, mHeight, mFormat);
Kévin PETIT377b2ec2014-02-03 12:35:36 +00001282 result.appendFormat(" size %zu, usage 0x%x, requested format 0x%x\n",
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001283 mSize, mUsage, mFormatRequested);
1284 result.appendFormat(" total buffers: %d, dequeued buffers: %d\n",
1285 mTotalBuffers, mActiveBuffers);
Kévin PETIT377b2ec2014-02-03 12:35:36 +00001286 result.appendFormat(" frame count: %d, last timestamp %" PRId64 "\n",
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001287 mFrameCount, mLastTimestamp);
1288 write(fd, result.string(), result.size());
1289 return OK;
1290}
1291
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001292const camera2_stream_ops *Camera2Device::StreamAdapter::getStreamOps() {
1293 return static_cast<camera2_stream_ops *>(this);
1294}
1295
1296ANativeWindow* Camera2Device::StreamAdapter::toANW(
1297 const camera2_stream_ops_t *w) {
1298 return static_cast<const StreamAdapter*>(w)->mConsumerInterface.get();
1299}
1300
1301int Camera2Device::StreamAdapter::dequeue_buffer(const camera2_stream_ops_t *w,
1302 buffer_handle_t** buffer) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001303 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001304 int res;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001305 StreamAdapter* stream =
1306 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
1307 if (stream->mState != ACTIVE) {
1308 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001309 return INVALID_OPERATION;
1310 }
1311
1312 ANativeWindow *a = toANW(w);
1313 ANativeWindowBuffer* anb;
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001314 res = native_window_dequeue_buffer_and_wait(a, &anb);
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001315 if (res != OK) {
1316 ALOGE("Stream %d dequeue: Error from native_window: %s (%d)", stream->mId,
1317 strerror(-res), res);
1318 return res;
1319 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001320
1321 *buffer = &(anb->handle);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001322 stream->mActiveBuffers++;
1323
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001324 ALOGVV("Stream %d dequeue: Buffer %p dequeued", stream->mId, (void*)(**buffer));
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001325 return res;
1326}
1327
1328int Camera2Device::StreamAdapter::enqueue_buffer(const camera2_stream_ops_t* w,
1329 int64_t timestamp,
1330 buffer_handle_t* buffer) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001331 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001332 StreamAdapter *stream =
1333 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001334 stream->mFrameCount++;
1335 ALOGVV("Stream %d enqueue: Frame %d (%p) captured at %lld ns",
James Donga289bf62012-09-05 16:46:36 -07001336 stream->mId, stream->mFrameCount, (void*)(*buffer), timestamp);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001337 int state = stream->mState;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001338 if (state != ACTIVE) {
1339 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1340 return INVALID_OPERATION;
1341 }
1342 ANativeWindow *a = toANW(w);
1343 status_t err;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001344
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001345 err = native_window_set_buffers_timestamp(a, timestamp);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001346 if (err != OK) {
1347 ALOGE("%s: Error setting timestamp on native window: %s (%d)",
1348 __FUNCTION__, strerror(-err), err);
1349 return err;
1350 }
1351 err = a->queueBuffer(a,
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001352 container_of(buffer, ANativeWindowBuffer, handle), -1);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001353 if (err != OK) {
1354 ALOGE("%s: Error queueing buffer to native window: %s (%d)",
1355 __FUNCTION__, strerror(-err), err);
James Dong31d377b2012-08-09 17:43:46 -07001356 return err;
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001357 }
James Dong31d377b2012-08-09 17:43:46 -07001358
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001359 stream->mActiveBuffers--;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001360 stream->mLastTimestamp = timestamp;
James Dong31d377b2012-08-09 17:43:46 -07001361 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001362}
1363
1364int Camera2Device::StreamAdapter::cancel_buffer(const camera2_stream_ops_t* w,
1365 buffer_handle_t* buffer) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001366 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001367 StreamAdapter *stream =
1368 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001369 ALOGVV("Stream %d cancel: Buffer %p",
1370 stream->mId, (void*)(*buffer));
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001371 if (stream->mState != ACTIVE) {
1372 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001373 return INVALID_OPERATION;
1374 }
James Dong31d377b2012-08-09 17:43:46 -07001375
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001376 ANativeWindow *a = toANW(w);
James Dong31d377b2012-08-09 17:43:46 -07001377 int err = a->cancelBuffer(a,
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001378 container_of(buffer, ANativeWindowBuffer, handle), -1);
James Dong31d377b2012-08-09 17:43:46 -07001379 if (err != OK) {
1380 ALOGE("%s: Error canceling buffer to native window: %s (%d)",
1381 __FUNCTION__, strerror(-err), err);
1382 return err;
1383 }
1384
1385 stream->mActiveBuffers--;
1386 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001387}
1388
1389int Camera2Device::StreamAdapter::set_crop(const camera2_stream_ops_t* w,
1390 int left, int top, int right, int bottom) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001391 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001392 int state = static_cast<const StreamAdapter*>(w)->mState;
1393 if (state != ACTIVE) {
1394 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1395 return INVALID_OPERATION;
1396 }
1397 ANativeWindow *a = toANW(w);
1398 android_native_rect_t crop = { left, top, right, bottom };
1399 return native_window_set_crop(a, &crop);
1400}
1401
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001402/**
1403 * Camera2Device::ReprocessStreamAdapter
1404 */
1405
1406#ifndef container_of
1407#define container_of(ptr, type, member) \
1408 (type *)((char*)(ptr) - offsetof(type, member))
1409#endif
1410
1411Camera2Device::ReprocessStreamAdapter::ReprocessStreamAdapter(camera2_device_t *d):
1412 mState(RELEASED),
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001413 mHal2Device(d),
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001414 mId(-1),
1415 mWidth(0), mHeight(0), mFormat(0),
1416 mActiveBuffers(0),
1417 mFrameCount(0)
1418{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001419 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001420 camera2_stream_in_ops::acquire_buffer = acquire_buffer;
1421 camera2_stream_in_ops::release_buffer = release_buffer;
1422}
1423
1424Camera2Device::ReprocessStreamAdapter::~ReprocessStreamAdapter() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001425 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001426 if (mState != RELEASED) {
1427 release();
1428 }
1429}
1430
1431status_t Camera2Device::ReprocessStreamAdapter::connectToDevice(
1432 const sp<StreamAdapter> &outputStream) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001433 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001434 status_t res;
1435 ALOGV("%s: E", __FUNCTION__);
1436
1437 if (mState != RELEASED) return INVALID_OPERATION;
1438 if (outputStream == NULL) {
1439 ALOGE("%s: Null base stream passed to reprocess stream adapter",
1440 __FUNCTION__);
1441 return BAD_VALUE;
1442 }
1443
1444 mBaseStream = outputStream;
1445 mWidth = outputStream->getWidth();
1446 mHeight = outputStream->getHeight();
1447 mFormat = outputStream->getFormat();
1448
1449 ALOGV("%s: New reprocess stream parameters %d x %d, format 0x%x",
1450 __FUNCTION__, mWidth, mHeight, mFormat);
1451
1452 // Allocate device-side stream interface
1453
1454 uint32_t id;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001455 res = mHal2Device->ops->allocate_reprocess_stream_from_stream(mHal2Device,
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001456 outputStream->getId(), getStreamOps(),
1457 &id);
1458 if (res != OK) {
1459 ALOGE("%s: Device reprocess stream allocation failed: %s (%d)",
1460 __FUNCTION__, strerror(-res), res);
1461 return res;
1462 }
1463
1464 ALOGV("%s: Allocated reprocess stream id %d based on stream %d",
1465 __FUNCTION__, id, outputStream->getId());
1466
1467 mId = id;
1468
1469 mState = ACTIVE;
1470
1471 return OK;
1472}
1473
1474status_t Camera2Device::ReprocessStreamAdapter::release() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001475 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001476 status_t res;
1477 ALOGV("%s: Releasing stream %d", __FUNCTION__, mId);
1478 if (mState >= ACTIVE) {
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001479 res = mHal2Device->ops->release_reprocess_stream(mHal2Device, mId);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001480 if (res != OK) {
1481 ALOGE("%s: Unable to release stream %d",
1482 __FUNCTION__, mId);
1483 return res;
1484 }
1485 }
1486
1487 List<QueueEntry>::iterator s;
1488 for (s = mQueue.begin(); s != mQueue.end(); s++) {
1489 sp<BufferReleasedListener> listener = s->releaseListener.promote();
1490 if (listener != 0) listener->onBufferReleased(s->handle);
1491 }
1492 for (s = mInFlightQueue.begin(); s != mInFlightQueue.end(); s++) {
1493 sp<BufferReleasedListener> listener = s->releaseListener.promote();
1494 if (listener != 0) listener->onBufferReleased(s->handle);
1495 }
1496 mQueue.clear();
1497 mInFlightQueue.clear();
1498
1499 mState = RELEASED;
1500 return OK;
1501}
1502
1503status_t Camera2Device::ReprocessStreamAdapter::pushIntoStream(
1504 buffer_handle_t *handle, const wp<BufferReleasedListener> &releaseListener) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001505 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001506 // TODO: Some error checking here would be nice
1507 ALOGV("%s: Pushing buffer %p to stream", __FUNCTION__, (void*)(*handle));
1508
1509 QueueEntry entry;
1510 entry.handle = handle;
1511 entry.releaseListener = releaseListener;
1512 mQueue.push_back(entry);
1513 return OK;
1514}
1515
1516status_t Camera2Device::ReprocessStreamAdapter::dump(int fd,
Igor Murashkinebe3f692012-10-12 16:56:11 -07001517 const Vector<String16>& /*args*/) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001518 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001519 String8 result =
1520 String8::format(" Reprocess stream %d: %d x %d, fmt 0x%x\n",
1521 mId, mWidth, mHeight, mFormat);
1522 result.appendFormat(" acquired buffers: %d\n",
1523 mActiveBuffers);
1524 result.appendFormat(" frame count: %d\n",
1525 mFrameCount);
1526 write(fd, result.string(), result.size());
1527 return OK;
1528}
1529
1530const camera2_stream_in_ops *Camera2Device::ReprocessStreamAdapter::getStreamOps() {
1531 return static_cast<camera2_stream_in_ops *>(this);
1532}
1533
1534int Camera2Device::ReprocessStreamAdapter::acquire_buffer(
1535 const camera2_stream_in_ops_t *w,
1536 buffer_handle_t** buffer) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001537 ATRACE_CALL();
Igor Murashkinebe3f692012-10-12 16:56:11 -07001538
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001539 ReprocessStreamAdapter* stream =
1540 const_cast<ReprocessStreamAdapter*>(
1541 static_cast<const ReprocessStreamAdapter*>(w));
1542 if (stream->mState != ACTIVE) {
1543 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
1544 return INVALID_OPERATION;
1545 }
1546
1547 if (stream->mQueue.empty()) {
1548 *buffer = NULL;
1549 return OK;
1550 }
1551
1552 QueueEntry &entry = *(stream->mQueue.begin());
1553
1554 *buffer = entry.handle;
1555
1556 stream->mInFlightQueue.push_back(entry);
1557 stream->mQueue.erase(stream->mQueue.begin());
1558
1559 stream->mActiveBuffers++;
1560
1561 ALOGV("Stream %d acquire: Buffer %p acquired", stream->mId,
1562 (void*)(**buffer));
1563 return OK;
1564}
1565
1566int Camera2Device::ReprocessStreamAdapter::release_buffer(
1567 const camera2_stream_in_ops_t* w,
1568 buffer_handle_t* buffer) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001569 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001570 ReprocessStreamAdapter *stream =
1571 const_cast<ReprocessStreamAdapter*>(
1572 static_cast<const ReprocessStreamAdapter*>(w) );
1573 stream->mFrameCount++;
1574 ALOGV("Reprocess stream %d release: Frame %d (%p)",
1575 stream->mId, stream->mFrameCount, (void*)*buffer);
1576 int state = stream->mState;
1577 if (state != ACTIVE) {
1578 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1579 return INVALID_OPERATION;
1580 }
1581 stream->mActiveBuffers--;
1582
1583 List<QueueEntry>::iterator s;
1584 for (s = stream->mInFlightQueue.begin(); s != stream->mInFlightQueue.end(); s++) {
1585 if ( s->handle == buffer ) break;
1586 }
1587 if (s == stream->mInFlightQueue.end()) {
1588 ALOGE("%s: Can't find buffer %p in in-flight list!", __FUNCTION__,
1589 buffer);
1590 return INVALID_OPERATION;
1591 }
1592
1593 sp<BufferReleasedListener> listener = s->releaseListener.promote();
1594 if (listener != 0) {
1595 listener->onBufferReleased(s->handle);
1596 } else {
1597 ALOGE("%s: Can't free buffer - missing listener", __FUNCTION__);
1598 }
1599 stream->mInFlightQueue.erase(s);
1600
1601 return OK;
1602}
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001603
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -07001604// camera 2 devices don't support reprocessing
1605status_t Camera2Device::createInputStream(
1606 uint32_t width, uint32_t height, int format, int *id) {
1607 ALOGE("%s: camera 2 devices don't support reprocessing", __FUNCTION__);
1608 return INVALID_OPERATION;
1609}
1610
1611// camera 2 devices don't support reprocessing
1612status_t Camera2Device::getInputBufferProducer(
1613 sp<IGraphicBufferProducer> *producer) {
1614 ALOGE("%s: camera 2 devices don't support reprocessing", __FUNCTION__);
1615 return INVALID_OPERATION;
1616}
1617
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001618}; // namespace android