blob: 43c8307084c9cee256734efa632ce2446e5961ff [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 Talvala6db981c2012-05-21 18:54:30 -0700243status_t Camera2Device::createStream(sp<ANativeWindow> consumer,
Zhijun He28c9b6f2014-08-08 12:00:47 -0700244 uint32_t width, uint32_t height, int format, 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);
Zhijun He28c9b6f2014-08-08 12:00:47 -0700250 size_t size = 0;
251 if (format == HAL_PIXEL_FORMAT_BLOB) {
252 size = getJpegBufferSize(width, height);
253 }
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700254 res = stream->connectToDevice(consumer, width, height, format, size);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700255 if (res != OK) {
256 ALOGE("%s: Camera %d: Unable to create stream (%d x %d, format %x):"
257 "%s (%d)",
258 __FUNCTION__, mId, width, height, format, strerror(-res), res);
259 return res;
260 }
261
262 *id = stream->getId();
263
264 mStreams.push_back(stream);
265 return OK;
266}
267
Zhijun He28c9b6f2014-08-08 12:00:47 -0700268ssize_t Camera2Device::getJpegBufferSize(uint32_t width, uint32_t height) const {
269 // Always give the max jpeg buffer size regardless of the actual jpeg resolution.
270 camera_metadata_ro_entry jpegBufMaxSize = mDeviceInfo.find(ANDROID_JPEG_MAX_SIZE);
271 if (jpegBufMaxSize.count == 0) {
272 ALOGE("%s: Camera %d: Can't find maximum JPEG size in static metadata!", __FUNCTION__, mId);
273 return BAD_VALUE;
274 }
275
276 return jpegBufMaxSize.data.i32[0];
277}
278
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700279status_t Camera2Device::createReprocessStreamFromStream(int outputId, int *id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700280 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700281 status_t res;
282 ALOGV("%s: E", __FUNCTION__);
283
284 bool found = false;
285 StreamList::iterator streamI;
286 for (streamI = mStreams.begin();
287 streamI != mStreams.end(); streamI++) {
288 if ((*streamI)->getId() == outputId) {
289 found = true;
290 break;
291 }
292 }
293 if (!found) {
294 ALOGE("%s: Camera %d: Output stream %d doesn't exist; can't create "
295 "reprocess stream from it!", __FUNCTION__, mId, outputId);
296 return BAD_VALUE;
297 }
298
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800299 sp<ReprocessStreamAdapter> stream = new ReprocessStreamAdapter(mHal2Device);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700300
301 res = stream->connectToDevice((*streamI));
302 if (res != OK) {
303 ALOGE("%s: Camera %d: Unable to create reprocessing stream from "\
304 "stream %d: %s (%d)", __FUNCTION__, mId, outputId,
305 strerror(-res), res);
306 return res;
307 }
308
309 *id = stream->getId();
310
311 mReprocessStreams.push_back(stream);
312 return OK;
313}
314
315
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700316status_t Camera2Device::getStreamInfo(int id,
317 uint32_t *width, uint32_t *height, uint32_t *format) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700318 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700319 ALOGV("%s: E", __FUNCTION__);
320 bool found = false;
321 StreamList::iterator streamI;
322 for (streamI = mStreams.begin();
323 streamI != mStreams.end(); streamI++) {
324 if ((*streamI)->getId() == id) {
325 found = true;
326 break;
327 }
328 }
329 if (!found) {
330 ALOGE("%s: Camera %d: Stream %d does not exist",
331 __FUNCTION__, mId, id);
332 return BAD_VALUE;
333 }
334
335 if (width) *width = (*streamI)->getWidth();
336 if (height) *height = (*streamI)->getHeight();
337 if (format) *format = (*streamI)->getFormat();
338
339 return OK;
340}
341
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -0700342status_t Camera2Device::setStreamTransform(int id,
343 int transform) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700344 ATRACE_CALL();
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -0700345 ALOGV("%s: E", __FUNCTION__);
346 bool found = false;
347 StreamList::iterator streamI;
348 for (streamI = mStreams.begin();
349 streamI != mStreams.end(); streamI++) {
350 if ((*streamI)->getId() == id) {
351 found = true;
352 break;
353 }
354 }
355 if (!found) {
356 ALOGE("%s: Camera %d: Stream %d does not exist",
357 __FUNCTION__, mId, id);
358 return BAD_VALUE;
359 }
360
361 return (*streamI)->setTransform(transform);
362}
363
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700364status_t Camera2Device::deleteStream(int id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700365 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700366 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700367 bool found = false;
368 for (StreamList::iterator streamI = mStreams.begin();
369 streamI != mStreams.end(); streamI++) {
370 if ((*streamI)->getId() == id) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700371 status_t res = (*streamI)->release();
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700372 if (res != OK) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700373 ALOGE("%s: Unable to release stream %d from HAL device: "
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700374 "%s (%d)", __FUNCTION__, id, strerror(-res), res);
375 return res;
376 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700377 mStreams.erase(streamI);
378 found = true;
379 break;
380 }
381 }
382 if (!found) {
383 ALOGE("%s: Camera %d: Unable to find stream %d to delete",
384 __FUNCTION__, mId, id);
385 return BAD_VALUE;
386 }
387 return OK;
388}
389
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700390status_t Camera2Device::deleteReprocessStream(int id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700391 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700392 ALOGV("%s: E", __FUNCTION__);
393 bool found = false;
394 for (ReprocessStreamList::iterator streamI = mReprocessStreams.begin();
395 streamI != mReprocessStreams.end(); streamI++) {
396 if ((*streamI)->getId() == id) {
397 status_t res = (*streamI)->release();
398 if (res != OK) {
399 ALOGE("%s: Unable to release reprocess stream %d from "
400 "HAL device: %s (%d)", __FUNCTION__, id,
401 strerror(-res), res);
402 return res;
403 }
404 mReprocessStreams.erase(streamI);
405 found = true;
406 break;
407 }
408 }
409 if (!found) {
410 ALOGE("%s: Camera %d: Unable to find stream %d to delete",
411 __FUNCTION__, mId, id);
412 return BAD_VALUE;
413 }
414 return OK;
415}
416
Igor Murashkine2d167e2014-08-19 16:19:59 -0700417status_t Camera2Device::configureStreams() {
418 ATRACE_CALL();
419 ALOGV("%s: E", __FUNCTION__);
420
421 /**
422 * HAL2 devices do not need to configure streams;
423 * streams are created on the fly.
424 */
425 ALOGW("%s: No-op for HAL2 devices", __FUNCTION__);
426
427 return OK;
428}
429
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700430
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700431status_t Camera2Device::createDefaultRequest(int templateId,
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700432 CameraMetadata *request) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700433 ATRACE_CALL();
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700434 status_t err;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700435 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700436 camera_metadata_t *rawRequest;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800437 err = mHal2Device->ops->construct_default_request(
438 mHal2Device, templateId, &rawRequest);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700439 request->acquire(rawRequest);
440 return err;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700441}
442
443status_t Camera2Device::waitUntilDrained() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700444 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700445 static const uint32_t kSleepTime = 50000; // 50 ms
446 static const uint32_t kMaxSleepTime = 10000000; // 10 s
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700447 ALOGV("%s: Camera %d: Starting wait", __FUNCTION__, mId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700448 if (mRequestQueue.getBufferCount() ==
449 CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS) return INVALID_OPERATION;
450
451 // TODO: Set up notifications from HAL, instead of sleeping here
452 uint32_t totalTime = 0;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800453 while (mHal2Device->ops->get_in_progress_count(mHal2Device) > 0) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700454 usleep(kSleepTime);
455 totalTime += kSleepTime;
456 if (totalTime > kMaxSleepTime) {
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700457 ALOGE("%s: Waited %d us, %d requests still in flight", __FUNCTION__,
Alex Rayf0eeb532013-03-17 03:23:18 -0700458 totalTime, mHal2Device->ops->get_in_progress_count(mHal2Device));
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700459 return TIMED_OUT;
460 }
461 }
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700462 ALOGV("%s: Camera %d: HAL is idle", __FUNCTION__, mId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700463 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700464}
465
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700466status_t Camera2Device::setNotifyCallback(NotificationListener *listener) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700467 ATRACE_CALL();
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700468 status_t res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800469 res = mHal2Device->ops->set_notify_callback(mHal2Device, notificationCallback,
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700470 reinterpret_cast<void*>(listener) );
471 if (res != OK) {
472 ALOGE("%s: Unable to set notification callback!", __FUNCTION__);
473 }
474 return res;
475}
476
Eino-Ville Talvala46910bd2013-07-18 19:15:17 -0700477bool Camera2Device::willNotify3A() {
478 return true;
479}
480
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700481void Camera2Device::notificationCallback(int32_t msg_type,
482 int32_t ext1,
483 int32_t ext2,
484 int32_t ext3,
485 void *user) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700486 ATRACE_CALL();
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700487 NotificationListener *listener = reinterpret_cast<NotificationListener*>(user);
488 ALOGV("%s: Notification %d, arguments %d, %d, %d", __FUNCTION__, msg_type,
489 ext1, ext2, ext3);
490 if (listener != NULL) {
491 switch (msg_type) {
492 case CAMERA2_MSG_ERROR:
Jianing Weicb0652e2014-03-12 18:29:36 -0700493 // TODO: This needs to be fixed. ext2 and ext3 need to be considered.
494 listener->notifyError(
495 ((ext1 == CAMERA2_MSG_ERROR_DEVICE)
496 || (ext1 == CAMERA2_MSG_ERROR_HARDWARE)) ?
497 ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE :
498 ICameraDeviceCallbacks::ERROR_CAMERA_SERVICE,
499 CaptureResultExtras());
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700500 break;
501 case CAMERA2_MSG_SHUTTER: {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700502 // TODO: Only needed for camera2 API, which is unsupported
503 // by HAL2 directly.
504 // nsecs_t timestamp = (nsecs_t)ext2 | ((nsecs_t)(ext3) << 32 );
505 // listener->notifyShutter(requestId, timestamp);
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700506 break;
507 }
508 case CAMERA2_MSG_AUTOFOCUS:
509 listener->notifyAutoFocus(ext1, ext2);
510 break;
511 case CAMERA2_MSG_AUTOEXPOSURE:
512 listener->notifyAutoExposure(ext1, ext2);
513 break;
514 case CAMERA2_MSG_AUTOWB:
515 listener->notifyAutoWhitebalance(ext1, ext2);
516 break;
517 default:
518 ALOGE("%s: Unknown notification %d (arguments %d, %d, %d)!",
519 __FUNCTION__, msg_type, ext1, ext2, ext3);
520 }
521 }
522}
523
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -0700524status_t Camera2Device::waitForNextFrame(nsecs_t timeout) {
525 return mFrameQueue.waitForBuffer(timeout);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700526}
527
Jianing Weicb0652e2014-03-12 18:29:36 -0700528status_t Camera2Device::getNextResult(CaptureResult *result) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700529 ATRACE_CALL();
Jianing Weicb0652e2014-03-12 18:29:36 -0700530 ALOGV("%s: get CaptureResult", __FUNCTION__);
531 if (result == NULL) {
532 ALOGE("%s: result pointer is NULL", __FUNCTION__);
533 return BAD_VALUE;
534 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700535 status_t res;
536 camera_metadata_t *rawFrame;
537 res = mFrameQueue.dequeue(&rawFrame);
Jianing Weicb0652e2014-03-12 18:29:36 -0700538 if (rawFrame == NULL) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700539 return NOT_ENOUGH_DATA;
540 } else if (res == OK) {
Jianing Weicb0652e2014-03-12 18:29:36 -0700541 result->mMetadata.acquire(rawFrame);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700542 }
Jianing Weicb0652e2014-03-12 18:29:36 -0700543
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700544 return res;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700545}
546
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700547status_t Camera2Device::triggerAutofocus(uint32_t id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700548 ATRACE_CALL();
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700549 status_t res;
550 ALOGV("%s: Triggering autofocus, id %d", __FUNCTION__, id);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800551 res = mHal2Device->ops->trigger_action(mHal2Device,
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700552 CAMERA2_TRIGGER_AUTOFOCUS, id, 0);
553 if (res != OK) {
554 ALOGE("%s: Error triggering autofocus (id %d)",
555 __FUNCTION__, id);
556 }
557 return res;
558}
559
560status_t Camera2Device::triggerCancelAutofocus(uint32_t id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700561 ATRACE_CALL();
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700562 status_t res;
563 ALOGV("%s: Canceling autofocus, id %d", __FUNCTION__, id);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800564 res = mHal2Device->ops->trigger_action(mHal2Device,
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700565 CAMERA2_TRIGGER_CANCEL_AUTOFOCUS, id, 0);
566 if (res != OK) {
567 ALOGE("%s: Error canceling autofocus (id %d)",
568 __FUNCTION__, id);
569 }
570 return res;
571}
572
573status_t Camera2Device::triggerPrecaptureMetering(uint32_t id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700574 ATRACE_CALL();
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700575 status_t res;
576 ALOGV("%s: Triggering precapture metering, id %d", __FUNCTION__, id);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800577 res = mHal2Device->ops->trigger_action(mHal2Device,
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700578 CAMERA2_TRIGGER_PRECAPTURE_METERING, id, 0);
579 if (res != OK) {
580 ALOGE("%s: Error triggering precapture metering (id %d)",
581 __FUNCTION__, id);
582 }
583 return res;
584}
585
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700586status_t Camera2Device::pushReprocessBuffer(int reprocessStreamId,
587 buffer_handle_t *buffer, wp<BufferReleasedListener> listener) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700588 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700589 ALOGV("%s: E", __FUNCTION__);
590 bool found = false;
591 status_t res = OK;
592 for (ReprocessStreamList::iterator streamI = mReprocessStreams.begin();
593 streamI != mReprocessStreams.end(); streamI++) {
594 if ((*streamI)->getId() == reprocessStreamId) {
595 res = (*streamI)->pushIntoStream(buffer, listener);
596 if (res != OK) {
597 ALOGE("%s: Unable to push buffer to reprocess stream %d: %s (%d)",
598 __FUNCTION__, reprocessStreamId, strerror(-res), res);
599 return res;
600 }
601 found = true;
602 break;
603 }
604 }
605 if (!found) {
606 ALOGE("%s: Camera %d: Unable to find reprocess stream %d",
607 __FUNCTION__, mId, reprocessStreamId);
608 res = BAD_VALUE;
609 }
610 return res;
611}
612
Jianing Weicb0652e2014-03-12 18:29:36 -0700613status_t Camera2Device::flush(int64_t* /*lastFrameNumber*/) {
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -0700614 ATRACE_CALL();
615
616 mRequestQueue.clear();
617 return waitUntilDrained();
618}
619
Zhijun He204e3292014-07-14 17:09:23 -0700620uint32_t Camera2Device::getDeviceVersion() {
621 ATRACE_CALL();
622 return mDeviceVersion;
623}
624
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700625/**
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700626 * Camera2Device::MetadataQueue
627 */
628
629Camera2Device::MetadataQueue::MetadataQueue():
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800630 mHal2Device(NULL),
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700631 mFrameCount(0),
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700632 mLatestRequestId(0),
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700633 mCount(0),
634 mStreamSlotCount(0),
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -0700635 mSignalConsumer(true)
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700636{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700637 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700638 camera2_request_queue_src_ops::dequeue_request = consumer_dequeue;
639 camera2_request_queue_src_ops::request_count = consumer_buffer_count;
640 camera2_request_queue_src_ops::free_request = consumer_free;
641
642 camera2_frame_queue_dst_ops::dequeue_frame = producer_dequeue;
643 camera2_frame_queue_dst_ops::cancel_frame = producer_cancel;
644 camera2_frame_queue_dst_ops::enqueue_frame = producer_enqueue;
645}
646
647Camera2Device::MetadataQueue::~MetadataQueue() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700648 ATRACE_CALL();
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -0700649 clear();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700650}
651
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700652// Connect to camera2 HAL as consumer (input requests/reprocessing)
653status_t Camera2Device::MetadataQueue::setConsumerDevice(camera2_device_t *d) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700654 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700655 status_t res;
656 res = d->ops->set_request_queue_src_ops(d,
657 this);
658 if (res != OK) return res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800659 mHal2Device = d;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700660 return OK;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700661}
662
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700663status_t Camera2Device::MetadataQueue::setProducerDevice(camera2_device_t *d) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700664 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700665 status_t res;
666 res = d->ops->set_frame_queue_dst_ops(d,
667 this);
668 return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700669}
670
671// Real interfaces
672status_t Camera2Device::MetadataQueue::enqueue(camera_metadata_t *buf) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700673 ATRACE_CALL();
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700674 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700675 Mutex::Autolock l(mMutex);
676
677 mCount++;
678 mEntries.push_back(buf);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700679
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700680 return signalConsumerLocked();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700681}
682
683int Camera2Device::MetadataQueue::getBufferCount() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700684 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700685 Mutex::Autolock l(mMutex);
686 if (mStreamSlotCount > 0) {
687 return CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS;
688 }
689 return mCount;
690}
691
692status_t Camera2Device::MetadataQueue::dequeue(camera_metadata_t **buf,
693 bool incrementCount)
694{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700695 ATRACE_CALL();
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700696 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700697 status_t res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700698 Mutex::Autolock l(mMutex);
699
700 if (mCount == 0) {
701 if (mStreamSlotCount == 0) {
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700702 ALOGVV("%s: Empty", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700703 *buf = NULL;
704 mSignalConsumer = true;
705 return OK;
706 }
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700707 ALOGVV("%s: Streaming %d frames to queue", __FUNCTION__,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700708 mStreamSlotCount);
709
710 for (List<camera_metadata_t*>::iterator slotEntry = mStreamSlot.begin();
711 slotEntry != mStreamSlot.end();
712 slotEntry++ ) {
713 size_t entries = get_camera_metadata_entry_count(*slotEntry);
714 size_t dataBytes = get_camera_metadata_data_count(*slotEntry);
715
716 camera_metadata_t *copy =
717 allocate_camera_metadata(entries, dataBytes);
718 append_camera_metadata(copy, *slotEntry);
719 mEntries.push_back(copy);
720 }
721 mCount = mStreamSlotCount;
722 }
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700723 ALOGVV("MetadataQueue: deque (%d buffers)", mCount);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700724 camera_metadata_t *b = *(mEntries.begin());
725 mEntries.erase(mEntries.begin());
726
727 if (incrementCount) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700728 ATRACE_INT("cam2_request", mFrameCount);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700729 camera_metadata_entry_t frameCount;
730 res = find_camera_metadata_entry(b,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700731 ANDROID_REQUEST_FRAME_COUNT,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700732 &frameCount);
733 if (res != OK) {
734 ALOGE("%s: Unable to add frame count: %s (%d)",
735 __FUNCTION__, strerror(-res), res);
736 } else {
737 *frameCount.data.i32 = mFrameCount;
738 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700739 mFrameCount++;
740 }
741
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700742 // Check for request ID, and if present, signal waiters.
743 camera_metadata_entry_t requestId;
744 res = find_camera_metadata_entry(b,
745 ANDROID_REQUEST_ID,
746 &requestId);
747 if (res == OK) {
748 mLatestRequestId = requestId.data.i32[0];
749 mNewRequestId.signal();
750 }
751
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700752 *buf = b;
753 mCount--;
754
755 return OK;
756}
757
758status_t Camera2Device::MetadataQueue::waitForBuffer(nsecs_t timeout)
759{
760 Mutex::Autolock l(mMutex);
761 status_t res;
762 while (mCount == 0) {
763 res = notEmpty.waitRelative(mMutex,timeout);
764 if (res != OK) return res;
765 }
766 return OK;
767}
768
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700769status_t Camera2Device::MetadataQueue::waitForDequeue(int32_t id,
770 nsecs_t timeout) {
771 Mutex::Autolock l(mMutex);
772 status_t res;
773 while (mLatestRequestId != id) {
774 nsecs_t startTime = systemTime();
775
776 res = mNewRequestId.waitRelative(mMutex, timeout);
777 if (res != OK) return res;
778
779 timeout -= (systemTime() - startTime);
780 }
781
782 return OK;
783}
784
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700785status_t Camera2Device::MetadataQueue::setStreamSlot(camera_metadata_t *buf)
786{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700787 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700788 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700789 Mutex::Autolock l(mMutex);
790 if (buf == NULL) {
791 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
792 mStreamSlotCount = 0;
793 return OK;
794 }
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700795
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700796 if (mStreamSlotCount > 1) {
797 List<camera_metadata_t*>::iterator deleter = ++mStreamSlot.begin();
798 freeBuffers(++mStreamSlot.begin(), mStreamSlot.end());
799 mStreamSlotCount = 1;
800 }
801 if (mStreamSlotCount == 1) {
802 free_camera_metadata( *(mStreamSlot.begin()) );
Chien-Yu Chen80de5dc2014-11-07 17:45:00 -0800803 *(mStreamSlot.begin()) = buf;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700804 } else {
Chien-Yu Chen80de5dc2014-11-07 17:45:00 -0800805 mStreamSlot.push_front(buf);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700806 mStreamSlotCount = 1;
807 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700808 return signalConsumerLocked();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700809}
810
811status_t Camera2Device::MetadataQueue::setStreamSlot(
812 const List<camera_metadata_t*> &bufs)
813{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700814 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700815 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700816 Mutex::Autolock l(mMutex);
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700817
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700818 if (mStreamSlotCount > 0) {
819 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
820 }
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700821 mStreamSlotCount = 0;
822 for (List<camera_metadata_t*>::const_iterator r = bufs.begin();
823 r != bufs.end(); r++) {
Chien-Yu Chen80de5dc2014-11-07 17:45:00 -0800824 mStreamSlot.push_back(*r);
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700825 mStreamSlotCount++;
826 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700827 return signalConsumerLocked();
828}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700829
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -0700830status_t Camera2Device::MetadataQueue::clear()
831{
832 ATRACE_CALL();
833 ALOGV("%s: E", __FUNCTION__);
834
835 Mutex::Autolock l(mMutex);
836
837 // Clear streaming slot
838 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
839 mStreamSlotCount = 0;
840
841 // Clear request queue
842 freeBuffers(mEntries.begin(), mEntries.end());
843 mCount = 0;
844 return OK;
845}
846
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700847status_t Camera2Device::MetadataQueue::dump(int fd,
Igor Murashkinebe3f692012-10-12 16:56:11 -0700848 const Vector<String16>& /*args*/) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700849 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700850 String8 result;
851 status_t notLocked;
852 notLocked = mMutex.tryLock();
853 if (notLocked) {
854 result.append(" (Unable to lock queue mutex)\n");
855 }
856 result.appendFormat(" Current frame number: %d\n", mFrameCount);
857 if (mStreamSlotCount == 0) {
858 result.append(" Stream slot: Empty\n");
859 write(fd, result.string(), result.size());
860 } else {
Kévin PETIT377b2ec2014-02-03 12:35:36 +0000861 result.appendFormat(" Stream slot: %zu entries\n",
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700862 mStreamSlot.size());
863 int i = 0;
864 for (List<camera_metadata_t*>::iterator r = mStreamSlot.begin();
865 r != mStreamSlot.end(); r++) {
866 result = String8::format(" Stream slot buffer %d:\n", i);
867 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700868 dump_indented_camera_metadata(*r, fd, 2, 10);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700869 i++;
870 }
871 }
872 if (mEntries.size() == 0) {
873 result = " Main queue is empty\n";
874 write(fd, result.string(), result.size());
875 } else {
Kévin PETIT377b2ec2014-02-03 12:35:36 +0000876 result = String8::format(" Main queue has %zu entries:\n",
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700877 mEntries.size());
878 int i = 0;
879 for (List<camera_metadata_t*>::iterator r = mEntries.begin();
880 r != mEntries.end(); r++) {
881 result = String8::format(" Queue entry %d:\n", i);
882 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700883 dump_indented_camera_metadata(*r, fd, 2, 10);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700884 i++;
885 }
886 }
887
888 if (notLocked == 0) {
889 mMutex.unlock();
890 }
891
892 return OK;
893}
894
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700895status_t Camera2Device::MetadataQueue::signalConsumerLocked() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700896 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700897 status_t res = OK;
898 notEmpty.signal();
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800899 if (mSignalConsumer && mHal2Device != NULL) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700900 mSignalConsumer = false;
901
902 mMutex.unlock();
903 ALOGV("%s: Signaling consumer", __FUNCTION__);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800904 res = mHal2Device->ops->notify_request_queue_not_empty(mHal2Device);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700905 mMutex.lock();
906 }
907 return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700908}
909
910status_t Camera2Device::MetadataQueue::freeBuffers(
911 List<camera_metadata_t*>::iterator start,
912 List<camera_metadata_t*>::iterator end)
913{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700914 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700915 while (start != end) {
916 free_camera_metadata(*start);
917 start = mStreamSlot.erase(start);
918 }
919 return OK;
920}
921
922Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
923 const camera2_request_queue_src_ops_t *q)
924{
925 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
926 return const_cast<MetadataQueue*>(cmq);
927}
928
929Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
930 const camera2_frame_queue_dst_ops_t *q)
931{
932 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
933 return const_cast<MetadataQueue*>(cmq);
934}
935
936int Camera2Device::MetadataQueue::consumer_buffer_count(
937 const camera2_request_queue_src_ops_t *q)
938{
939 MetadataQueue *queue = getInstance(q);
940 return queue->getBufferCount();
941}
942
943int Camera2Device::MetadataQueue::consumer_dequeue(
944 const camera2_request_queue_src_ops_t *q,
945 camera_metadata_t **buffer)
946{
947 MetadataQueue *queue = getInstance(q);
948 return queue->dequeue(buffer, true);
949}
950
951int Camera2Device::MetadataQueue::consumer_free(
952 const camera2_request_queue_src_ops_t *q,
953 camera_metadata_t *old_buffer)
954{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700955 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700956 MetadataQueue *queue = getInstance(q);
Igor Murashkinebe3f692012-10-12 16:56:11 -0700957 (void)queue;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700958 free_camera_metadata(old_buffer);
959 return OK;
960}
961
962int Camera2Device::MetadataQueue::producer_dequeue(
Igor Murashkinebe3f692012-10-12 16:56:11 -0700963 const camera2_frame_queue_dst_ops_t * /*q*/,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700964 size_t entries, size_t bytes,
965 camera_metadata_t **buffer)
966{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700967 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700968 camera_metadata_t *new_buffer =
969 allocate_camera_metadata(entries, bytes);
970 if (new_buffer == NULL) return NO_MEMORY;
971 *buffer = new_buffer;
972 return OK;
973}
974
975int Camera2Device::MetadataQueue::producer_cancel(
Igor Murashkinebe3f692012-10-12 16:56:11 -0700976 const camera2_frame_queue_dst_ops_t * /*q*/,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700977 camera_metadata_t *old_buffer)
978{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700979 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700980 free_camera_metadata(old_buffer);
981 return OK;
982}
983
984int Camera2Device::MetadataQueue::producer_enqueue(
985 const camera2_frame_queue_dst_ops_t *q,
986 camera_metadata_t *filled_buffer)
987{
988 MetadataQueue *queue = getInstance(q);
989 return queue->enqueue(filled_buffer);
990}
991
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700992/**
993 * Camera2Device::StreamAdapter
994 */
995
996#ifndef container_of
997#define container_of(ptr, type, member) \
998 (type *)((char*)(ptr) - offsetof(type, member))
999#endif
1000
1001Camera2Device::StreamAdapter::StreamAdapter(camera2_device_t *d):
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001002 mState(RELEASED),
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001003 mHal2Device(d),
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001004 mId(-1),
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001005 mWidth(0), mHeight(0), mFormat(0), mSize(0), mUsage(0),
1006 mMaxProducerBuffers(0), mMaxConsumerBuffers(0),
1007 mTotalBuffers(0),
1008 mFormatRequested(0),
1009 mActiveBuffers(0),
1010 mFrameCount(0),
1011 mLastTimestamp(0)
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001012{
1013 camera2_stream_ops::dequeue_buffer = dequeue_buffer;
1014 camera2_stream_ops::enqueue_buffer = enqueue_buffer;
1015 camera2_stream_ops::cancel_buffer = cancel_buffer;
1016 camera2_stream_ops::set_crop = set_crop;
1017}
1018
1019Camera2Device::StreamAdapter::~StreamAdapter() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001020 ATRACE_CALL();
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001021 if (mState != RELEASED) {
1022 release();
1023 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001024}
1025
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001026status_t Camera2Device::StreamAdapter::connectToDevice(
1027 sp<ANativeWindow> consumer,
1028 uint32_t width, uint32_t height, int format, size_t size) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001029 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001030 status_t res;
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -07001031 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001032
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001033 if (mState != RELEASED) return INVALID_OPERATION;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001034 if (consumer == NULL) {
1035 ALOGE("%s: Null consumer passed to stream adapter", __FUNCTION__);
1036 return BAD_VALUE;
1037 }
1038
Colin Crosse5729fa2014-03-21 15:04:25 -07001039 ALOGV("%s: New stream parameters %d x %d, format 0x%x, size %zu",
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001040 __FUNCTION__, width, height, format, size);
1041
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001042 mConsumerInterface = consumer;
1043 mWidth = width;
1044 mHeight = height;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001045 mSize = (format == HAL_PIXEL_FORMAT_BLOB) ? size : 0;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001046 mFormatRequested = format;
1047
1048 // Allocate device-side stream interface
1049
1050 uint32_t id;
1051 uint32_t formatActual;
1052 uint32_t usage;
1053 uint32_t maxBuffers = 2;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001054 res = mHal2Device->ops->allocate_stream(mHal2Device,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001055 mWidth, mHeight, mFormatRequested, getStreamOps(),
1056 &id, &formatActual, &usage, &maxBuffers);
1057 if (res != OK) {
1058 ALOGE("%s: Device stream allocation failed: %s (%d)",
1059 __FUNCTION__, strerror(-res), res);
1060 return res;
1061 }
1062
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001063 ALOGV("%s: Allocated stream id %d, actual format 0x%x, "
1064 "usage 0x%x, producer wants %d buffers", __FUNCTION__,
1065 id, formatActual, usage, maxBuffers);
1066
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001067 mId = id;
1068 mFormat = formatActual;
1069 mUsage = usage;
1070 mMaxProducerBuffers = maxBuffers;
1071
1072 mState = ALLOCATED;
1073
1074 // Configure consumer-side ANativeWindow interface
1075 res = native_window_api_connect(mConsumerInterface.get(),
1076 NATIVE_WINDOW_API_CAMERA);
1077 if (res != OK) {
1078 ALOGE("%s: Unable to connect to native window for stream %d",
1079 __FUNCTION__, mId);
1080
1081 return res;
1082 }
1083
1084 mState = CONNECTED;
1085
1086 res = native_window_set_usage(mConsumerInterface.get(), mUsage);
1087 if (res != OK) {
1088 ALOGE("%s: Unable to configure usage %08x for stream %d",
1089 __FUNCTION__, mUsage, mId);
1090 return res;
1091 }
1092
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001093 res = native_window_set_scaling_mode(mConsumerInterface.get(),
1094 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
1095 if (res != OK) {
1096 ALOGE("%s: Unable to configure stream scaling: %s (%d)",
1097 __FUNCTION__, strerror(-res), res);
1098 return res;
1099 }
1100
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001101 res = setTransform(0);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001102 if (res != OK) {
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001103 return res;
1104 }
1105
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001106 if (mFormat == HAL_PIXEL_FORMAT_BLOB) {
Eino-Ville Talvala7d70c5e2014-07-24 18:10:23 -07001107 res = native_window_set_buffers_dimensions(mConsumerInterface.get(),
1108 mSize, 1);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001109 if (res != OK) {
Eino-Ville Talvala7d70c5e2014-07-24 18:10:23 -07001110 ALOGE("%s: Unable to configure compressed stream buffer dimensions"
Colin Crosse5729fa2014-03-21 15:04:25 -07001111 " %d x %d, size %zu for stream %d",
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001112 __FUNCTION__, mWidth, mHeight, mSize, mId);
1113 return res;
1114 }
1115 } else {
Eino-Ville Talvala7d70c5e2014-07-24 18:10:23 -07001116 res = native_window_set_buffers_dimensions(mConsumerInterface.get(),
1117 mWidth, mHeight);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001118 if (res != OK) {
Eino-Ville Talvala7d70c5e2014-07-24 18:10:23 -07001119 ALOGE("%s: Unable to configure stream buffer dimensions"
1120 " %d x %d for stream %d",
1121 __FUNCTION__, mWidth, mHeight, mId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001122 return res;
1123 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001124 }
1125
Eino-Ville Talvala7d70c5e2014-07-24 18:10:23 -07001126 res = native_window_set_buffers_format(mConsumerInterface.get(), mFormat);
1127 if (res != OK) {
1128 ALOGE("%s: Unable to configure stream buffer format"
1129 " %#x for stream %d",
1130 __FUNCTION__, mFormat, mId);
1131 return res;
1132 }
1133
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001134 int maxConsumerBuffers;
1135 res = mConsumerInterface->query(mConsumerInterface.get(),
1136 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &maxConsumerBuffers);
1137 if (res != OK) {
1138 ALOGE("%s: Unable to query consumer undequeued"
1139 " buffer count for stream %d", __FUNCTION__, mId);
1140 return res;
1141 }
1142 mMaxConsumerBuffers = maxConsumerBuffers;
1143
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001144 ALOGV("%s: Consumer wants %d buffers", __FUNCTION__,
1145 mMaxConsumerBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001146
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001147 mTotalBuffers = mMaxConsumerBuffers + mMaxProducerBuffers;
1148 mActiveBuffers = 0;
1149 mFrameCount = 0;
1150 mLastTimestamp = 0;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001151
1152 res = native_window_set_buffer_count(mConsumerInterface.get(),
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001153 mTotalBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001154 if (res != OK) {
1155 ALOGE("%s: Unable to set buffer count for stream %d",
1156 __FUNCTION__, mId);
1157 return res;
1158 }
1159
1160 // Register allocated buffers with HAL device
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001161 buffer_handle_t *buffers = new buffer_handle_t[mTotalBuffers];
1162 ANativeWindowBuffer **anwBuffers = new ANativeWindowBuffer*[mTotalBuffers];
1163 uint32_t bufferIdx = 0;
1164 for (; bufferIdx < mTotalBuffers; bufferIdx++) {
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001165 res = native_window_dequeue_buffer_and_wait(mConsumerInterface.get(),
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001166 &anwBuffers[bufferIdx]);
1167 if (res != OK) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001168 ALOGE("%s: Unable to dequeue buffer %d for initial registration for "
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001169 "stream %d", __FUNCTION__, bufferIdx, mId);
1170 goto cleanUpBuffers;
1171 }
1172
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001173 buffers[bufferIdx] = anwBuffers[bufferIdx]->handle;
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001174 ALOGV("%s: Buffer %p allocated", __FUNCTION__, (void*)buffers[bufferIdx]);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001175 }
1176
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001177 ALOGV("%s: Registering %d buffers with camera HAL", __FUNCTION__, mTotalBuffers);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001178 res = mHal2Device->ops->register_stream_buffers(mHal2Device,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001179 mId,
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001180 mTotalBuffers,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001181 buffers);
1182 if (res != OK) {
1183 ALOGE("%s: Unable to register buffers with HAL device for stream %d",
1184 __FUNCTION__, mId);
1185 } else {
1186 mState = ACTIVE;
1187 }
1188
1189cleanUpBuffers:
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001190 ALOGV("%s: Cleaning up %d buffers", __FUNCTION__, bufferIdx);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001191 for (uint32_t i = 0; i < bufferIdx; i++) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001192 res = mConsumerInterface->cancelBuffer(mConsumerInterface.get(),
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001193 anwBuffers[i], -1);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001194 if (res != OK) {
1195 ALOGE("%s: Unable to cancel buffer %d after registration",
1196 __FUNCTION__, i);
1197 }
1198 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001199 delete[] anwBuffers;
1200 delete[] buffers;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001201
1202 return res;
1203}
1204
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001205status_t Camera2Device::StreamAdapter::release() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001206 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001207 status_t res;
Eino-Ville Talvala02f84572013-04-23 15:16:57 -07001208 ALOGV("%s: Releasing stream %d (%d x %d, format %d)", __FUNCTION__, mId,
1209 mWidth, mHeight, mFormat);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001210 if (mState >= ALLOCATED) {
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001211 res = mHal2Device->ops->release_stream(mHal2Device, mId);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001212 if (res != OK) {
1213 ALOGE("%s: Unable to release stream %d",
1214 __FUNCTION__, mId);
1215 return res;
1216 }
1217 }
1218 if (mState >= CONNECTED) {
1219 res = native_window_api_disconnect(mConsumerInterface.get(),
1220 NATIVE_WINDOW_API_CAMERA);
Igor Murashkina1e5dcc2012-10-02 15:21:31 -07001221
1222 /* this is not an error. if client calling process dies,
1223 the window will also die and all calls to it will return
1224 DEAD_OBJECT, thus it's already "disconnected" */
1225 if (res == DEAD_OBJECT) {
1226 ALOGW("%s: While disconnecting stream %d from native window, the"
1227 " native window died from under us", __FUNCTION__, mId);
1228 }
1229 else if (res != OK) {
1230 ALOGE("%s: Unable to disconnect stream %d from native window (error %d %s)",
1231 __FUNCTION__, mId, res, strerror(-res));
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001232 return res;
1233 }
1234 }
1235 mId = -1;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001236 mState = RELEASED;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001237 return OK;
1238}
1239
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001240status_t Camera2Device::StreamAdapter::setTransform(int transform) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001241 ATRACE_CALL();
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001242 status_t res;
1243 if (mState < CONNECTED) {
1244 ALOGE("%s: Cannot set transform on unconnected stream", __FUNCTION__);
1245 return INVALID_OPERATION;
1246 }
1247 res = native_window_set_buffers_transform(mConsumerInterface.get(),
1248 transform);
1249 if (res != OK) {
1250 ALOGE("%s: Unable to configure stream transform to %x: %s (%d)",
1251 __FUNCTION__, transform, strerror(-res), res);
1252 }
1253 return res;
1254}
1255
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001256status_t Camera2Device::StreamAdapter::dump(int fd,
Igor Murashkinebe3f692012-10-12 16:56:11 -07001257 const Vector<String16>& /*args*/) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001258 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001259 String8 result = String8::format(" Stream %d: %d x %d, format 0x%x\n",
1260 mId, mWidth, mHeight, mFormat);
Kévin PETIT377b2ec2014-02-03 12:35:36 +00001261 result.appendFormat(" size %zu, usage 0x%x, requested format 0x%x\n",
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001262 mSize, mUsage, mFormatRequested);
1263 result.appendFormat(" total buffers: %d, dequeued buffers: %d\n",
1264 mTotalBuffers, mActiveBuffers);
Kévin PETIT377b2ec2014-02-03 12:35:36 +00001265 result.appendFormat(" frame count: %d, last timestamp %" PRId64 "\n",
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001266 mFrameCount, mLastTimestamp);
1267 write(fd, result.string(), result.size());
1268 return OK;
1269}
1270
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001271const camera2_stream_ops *Camera2Device::StreamAdapter::getStreamOps() {
1272 return static_cast<camera2_stream_ops *>(this);
1273}
1274
1275ANativeWindow* Camera2Device::StreamAdapter::toANW(
1276 const camera2_stream_ops_t *w) {
1277 return static_cast<const StreamAdapter*>(w)->mConsumerInterface.get();
1278}
1279
1280int Camera2Device::StreamAdapter::dequeue_buffer(const camera2_stream_ops_t *w,
1281 buffer_handle_t** buffer) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001282 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001283 int res;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001284 StreamAdapter* stream =
1285 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
1286 if (stream->mState != ACTIVE) {
1287 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001288 return INVALID_OPERATION;
1289 }
1290
1291 ANativeWindow *a = toANW(w);
1292 ANativeWindowBuffer* anb;
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001293 res = native_window_dequeue_buffer_and_wait(a, &anb);
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001294 if (res != OK) {
1295 ALOGE("Stream %d dequeue: Error from native_window: %s (%d)", stream->mId,
1296 strerror(-res), res);
1297 return res;
1298 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001299
1300 *buffer = &(anb->handle);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001301 stream->mActiveBuffers++;
1302
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001303 ALOGVV("Stream %d dequeue: Buffer %p dequeued", stream->mId, (void*)(**buffer));
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001304 return res;
1305}
1306
1307int Camera2Device::StreamAdapter::enqueue_buffer(const camera2_stream_ops_t* w,
1308 int64_t timestamp,
1309 buffer_handle_t* buffer) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001310 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001311 StreamAdapter *stream =
1312 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001313 stream->mFrameCount++;
1314 ALOGVV("Stream %d enqueue: Frame %d (%p) captured at %lld ns",
James Donga289bf62012-09-05 16:46:36 -07001315 stream->mId, stream->mFrameCount, (void*)(*buffer), timestamp);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001316 int state = stream->mState;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001317 if (state != ACTIVE) {
1318 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1319 return INVALID_OPERATION;
1320 }
1321 ANativeWindow *a = toANW(w);
1322 status_t err;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001323
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001324 err = native_window_set_buffers_timestamp(a, timestamp);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001325 if (err != OK) {
1326 ALOGE("%s: Error setting timestamp on native window: %s (%d)",
1327 __FUNCTION__, strerror(-err), err);
1328 return err;
1329 }
1330 err = a->queueBuffer(a,
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001331 container_of(buffer, ANativeWindowBuffer, handle), -1);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001332 if (err != OK) {
1333 ALOGE("%s: Error queueing buffer to native window: %s (%d)",
1334 __FUNCTION__, strerror(-err), err);
James Dong31d377b2012-08-09 17:43:46 -07001335 return err;
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001336 }
James Dong31d377b2012-08-09 17:43:46 -07001337
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001338 stream->mActiveBuffers--;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001339 stream->mLastTimestamp = timestamp;
James Dong31d377b2012-08-09 17:43:46 -07001340 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001341}
1342
1343int Camera2Device::StreamAdapter::cancel_buffer(const camera2_stream_ops_t* w,
1344 buffer_handle_t* buffer) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001345 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001346 StreamAdapter *stream =
1347 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001348 ALOGVV("Stream %d cancel: Buffer %p",
1349 stream->mId, (void*)(*buffer));
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001350 if (stream->mState != ACTIVE) {
1351 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001352 return INVALID_OPERATION;
1353 }
James Dong31d377b2012-08-09 17:43:46 -07001354
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001355 ANativeWindow *a = toANW(w);
James Dong31d377b2012-08-09 17:43:46 -07001356 int err = a->cancelBuffer(a,
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001357 container_of(buffer, ANativeWindowBuffer, handle), -1);
James Dong31d377b2012-08-09 17:43:46 -07001358 if (err != OK) {
1359 ALOGE("%s: Error canceling buffer to native window: %s (%d)",
1360 __FUNCTION__, strerror(-err), err);
1361 return err;
1362 }
1363
1364 stream->mActiveBuffers--;
1365 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001366}
1367
1368int Camera2Device::StreamAdapter::set_crop(const camera2_stream_ops_t* w,
1369 int left, int top, int right, int bottom) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001370 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001371 int state = static_cast<const StreamAdapter*>(w)->mState;
1372 if (state != ACTIVE) {
1373 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1374 return INVALID_OPERATION;
1375 }
1376 ANativeWindow *a = toANW(w);
1377 android_native_rect_t crop = { left, top, right, bottom };
1378 return native_window_set_crop(a, &crop);
1379}
1380
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001381/**
1382 * Camera2Device::ReprocessStreamAdapter
1383 */
1384
1385#ifndef container_of
1386#define container_of(ptr, type, member) \
1387 (type *)((char*)(ptr) - offsetof(type, member))
1388#endif
1389
1390Camera2Device::ReprocessStreamAdapter::ReprocessStreamAdapter(camera2_device_t *d):
1391 mState(RELEASED),
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001392 mHal2Device(d),
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001393 mId(-1),
1394 mWidth(0), mHeight(0), mFormat(0),
1395 mActiveBuffers(0),
1396 mFrameCount(0)
1397{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001398 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001399 camera2_stream_in_ops::acquire_buffer = acquire_buffer;
1400 camera2_stream_in_ops::release_buffer = release_buffer;
1401}
1402
1403Camera2Device::ReprocessStreamAdapter::~ReprocessStreamAdapter() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001404 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001405 if (mState != RELEASED) {
1406 release();
1407 }
1408}
1409
1410status_t Camera2Device::ReprocessStreamAdapter::connectToDevice(
1411 const sp<StreamAdapter> &outputStream) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001412 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001413 status_t res;
1414 ALOGV("%s: E", __FUNCTION__);
1415
1416 if (mState != RELEASED) return INVALID_OPERATION;
1417 if (outputStream == NULL) {
1418 ALOGE("%s: Null base stream passed to reprocess stream adapter",
1419 __FUNCTION__);
1420 return BAD_VALUE;
1421 }
1422
1423 mBaseStream = outputStream;
1424 mWidth = outputStream->getWidth();
1425 mHeight = outputStream->getHeight();
1426 mFormat = outputStream->getFormat();
1427
1428 ALOGV("%s: New reprocess stream parameters %d x %d, format 0x%x",
1429 __FUNCTION__, mWidth, mHeight, mFormat);
1430
1431 // Allocate device-side stream interface
1432
1433 uint32_t id;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001434 res = mHal2Device->ops->allocate_reprocess_stream_from_stream(mHal2Device,
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001435 outputStream->getId(), getStreamOps(),
1436 &id);
1437 if (res != OK) {
1438 ALOGE("%s: Device reprocess stream allocation failed: %s (%d)",
1439 __FUNCTION__, strerror(-res), res);
1440 return res;
1441 }
1442
1443 ALOGV("%s: Allocated reprocess stream id %d based on stream %d",
1444 __FUNCTION__, id, outputStream->getId());
1445
1446 mId = id;
1447
1448 mState = ACTIVE;
1449
1450 return OK;
1451}
1452
1453status_t Camera2Device::ReprocessStreamAdapter::release() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001454 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001455 status_t res;
1456 ALOGV("%s: Releasing stream %d", __FUNCTION__, mId);
1457 if (mState >= ACTIVE) {
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001458 res = mHal2Device->ops->release_reprocess_stream(mHal2Device, mId);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001459 if (res != OK) {
1460 ALOGE("%s: Unable to release stream %d",
1461 __FUNCTION__, mId);
1462 return res;
1463 }
1464 }
1465
1466 List<QueueEntry>::iterator s;
1467 for (s = mQueue.begin(); s != mQueue.end(); s++) {
1468 sp<BufferReleasedListener> listener = s->releaseListener.promote();
1469 if (listener != 0) listener->onBufferReleased(s->handle);
1470 }
1471 for (s = mInFlightQueue.begin(); s != mInFlightQueue.end(); s++) {
1472 sp<BufferReleasedListener> listener = s->releaseListener.promote();
1473 if (listener != 0) listener->onBufferReleased(s->handle);
1474 }
1475 mQueue.clear();
1476 mInFlightQueue.clear();
1477
1478 mState = RELEASED;
1479 return OK;
1480}
1481
1482status_t Camera2Device::ReprocessStreamAdapter::pushIntoStream(
1483 buffer_handle_t *handle, const wp<BufferReleasedListener> &releaseListener) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001484 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001485 // TODO: Some error checking here would be nice
1486 ALOGV("%s: Pushing buffer %p to stream", __FUNCTION__, (void*)(*handle));
1487
1488 QueueEntry entry;
1489 entry.handle = handle;
1490 entry.releaseListener = releaseListener;
1491 mQueue.push_back(entry);
1492 return OK;
1493}
1494
1495status_t Camera2Device::ReprocessStreamAdapter::dump(int fd,
Igor Murashkinebe3f692012-10-12 16:56:11 -07001496 const Vector<String16>& /*args*/) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001497 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001498 String8 result =
1499 String8::format(" Reprocess stream %d: %d x %d, fmt 0x%x\n",
1500 mId, mWidth, mHeight, mFormat);
1501 result.appendFormat(" acquired buffers: %d\n",
1502 mActiveBuffers);
1503 result.appendFormat(" frame count: %d\n",
1504 mFrameCount);
1505 write(fd, result.string(), result.size());
1506 return OK;
1507}
1508
1509const camera2_stream_in_ops *Camera2Device::ReprocessStreamAdapter::getStreamOps() {
1510 return static_cast<camera2_stream_in_ops *>(this);
1511}
1512
1513int Camera2Device::ReprocessStreamAdapter::acquire_buffer(
1514 const camera2_stream_in_ops_t *w,
1515 buffer_handle_t** buffer) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001516 ATRACE_CALL();
Igor Murashkinebe3f692012-10-12 16:56:11 -07001517
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001518 ReprocessStreamAdapter* stream =
1519 const_cast<ReprocessStreamAdapter*>(
1520 static_cast<const ReprocessStreamAdapter*>(w));
1521 if (stream->mState != ACTIVE) {
1522 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
1523 return INVALID_OPERATION;
1524 }
1525
1526 if (stream->mQueue.empty()) {
1527 *buffer = NULL;
1528 return OK;
1529 }
1530
1531 QueueEntry &entry = *(stream->mQueue.begin());
1532
1533 *buffer = entry.handle;
1534
1535 stream->mInFlightQueue.push_back(entry);
1536 stream->mQueue.erase(stream->mQueue.begin());
1537
1538 stream->mActiveBuffers++;
1539
1540 ALOGV("Stream %d acquire: Buffer %p acquired", stream->mId,
1541 (void*)(**buffer));
1542 return OK;
1543}
1544
1545int Camera2Device::ReprocessStreamAdapter::release_buffer(
1546 const camera2_stream_in_ops_t* w,
1547 buffer_handle_t* buffer) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001548 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001549 ReprocessStreamAdapter *stream =
1550 const_cast<ReprocessStreamAdapter*>(
1551 static_cast<const ReprocessStreamAdapter*>(w) );
1552 stream->mFrameCount++;
1553 ALOGV("Reprocess stream %d release: Frame %d (%p)",
1554 stream->mId, stream->mFrameCount, (void*)*buffer);
1555 int state = stream->mState;
1556 if (state != ACTIVE) {
1557 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1558 return INVALID_OPERATION;
1559 }
1560 stream->mActiveBuffers--;
1561
1562 List<QueueEntry>::iterator s;
1563 for (s = stream->mInFlightQueue.begin(); s != stream->mInFlightQueue.end(); s++) {
1564 if ( s->handle == buffer ) break;
1565 }
1566 if (s == stream->mInFlightQueue.end()) {
1567 ALOGE("%s: Can't find buffer %p in in-flight list!", __FUNCTION__,
1568 buffer);
1569 return INVALID_OPERATION;
1570 }
1571
1572 sp<BufferReleasedListener> listener = s->releaseListener.promote();
1573 if (listener != 0) {
1574 listener->onBufferReleased(s->handle);
1575 } else {
1576 ALOGE("%s: Can't free buffer - missing listener", __FUNCTION__);
1577 }
1578 stream->mInFlightQueue.erase(s);
1579
1580 return OK;
1581}
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001582
1583}; // namespace android