blob: d473a764d564bfde262eef6d2009e10457a001a6 [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
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070056status_t Camera2Device::initialize(camera_module_t *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
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -070071 res = CameraService::filterOpenErrorCode(module->common.methods->open(
72 &module->common, name, reinterpret_cast<hw_device_t**>(&device)));
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070073
74 if (res != OK) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070075 ALOGE("%s: Could not open camera %d: %s (%d)", __FUNCTION__,
76 mId, strerror(-res), res);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070077 return res;
78 }
79
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -070080 if (device->common.version != CAMERA_DEVICE_API_VERSION_2_0) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070081 ALOGE("%s: Could not open camera %d: "
82 "Camera device is not version %x, reports %x instead",
83 __FUNCTION__, mId, CAMERA_DEVICE_API_VERSION_2_0,
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -070084 device->common.version);
85 device->common.close(&device->common);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070086 return BAD_VALUE;
87 }
88
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070089 camera_info info;
90 res = module->get_camera_info(mId, &info);
91 if (res != OK ) return res;
92
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -070093 if (info.device_version != device->common.version) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070094 ALOGE("%s: HAL reporting mismatched camera_info version (%x)"
95 " and device version (%x).", __FUNCTION__,
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -070096 device->common.version, info.device_version);
97 device->common.close(&device->common);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070098 return BAD_VALUE;
99 }
100
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700101 res = mRequestQueue.setConsumerDevice(device);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700102 if (res != OK) {
103 ALOGE("%s: Camera %d: Unable to connect request queue to device: %s (%d)",
104 __FUNCTION__, mId, strerror(-res), res);
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700105 device->common.close(&device->common);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700106 return res;
107 }
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700108 res = mFrameQueue.setProducerDevice(device);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700109 if (res != OK) {
110 ALOGE("%s: Camera %d: Unable to connect frame queue to device: %s (%d)",
111 __FUNCTION__, mId, strerror(-res), res);
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700112 device->common.close(&device->common);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700113 return res;
114 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700115
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700116 res = device->ops->set_notify_callback(device, notificationCallback,
117 NULL);
118 if (res != OK) {
119 ALOGE("%s: Camera %d: Unable to initialize notification callback!",
120 __FUNCTION__, mId);
121 device->common.close(&device->common);
122 return res;
123 }
124
125 mDeviceInfo = info.static_camera_characteristics;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800126 mHal2Device = device;
Zhijun He204e3292014-07-14 17:09:23 -0700127 mDeviceVersion = device->common.version;
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700128
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700129 return OK;
130}
131
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700132status_t Camera2Device::disconnect() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700133 ATRACE_CALL();
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700134 status_t res = OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800135 if (mHal2Device) {
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700136 ALOGV("%s: Closing device for camera %d", __FUNCTION__, mId);
137
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800138 int inProgressCount = mHal2Device->ops->get_in_progress_count(mHal2Device);
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700139 if (inProgressCount > 0) {
140 ALOGW("%s: Closing camera device %d with %d requests in flight!",
141 __FUNCTION__, mId, inProgressCount);
142 }
Eino-Ville Talvalac62bb782012-09-24 13:44:07 -0700143 mReprocessStreams.clear();
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700144 mStreams.clear();
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800145 res = mHal2Device->common.close(&mHal2Device->common);
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700146 if (res != OK) {
147 ALOGE("%s: Could not close camera %d: %s (%d)",
148 __FUNCTION__,
149 mId, strerror(-res), res);
150 }
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800151 mHal2Device = NULL;
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700152 ALOGV("%s: Shutdown complete", __FUNCTION__);
153 }
154 return res;
155}
156
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700157status_t Camera2Device::dump(int fd, const Vector<String16>& args) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700158 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700159 String8 result;
Eino-Ville Talvala97197152012-08-06 14:25:19 -0700160 int detailLevel = 0;
161 int n = args.size();
162 String16 detailOption("-d");
163 for (int i = 0; i + 1 < n; i++) {
164 if (args[i] == detailOption) {
165 String8 levelStr(args[i+1]);
166 detailLevel = atoi(levelStr.string());
167 }
168 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700169
Eino-Ville Talvala603b12e2012-08-08 09:25:58 -0700170 result.appendFormat(" Camera2Device[%d] dump (detail level %d):\n",
171 mId, detailLevel);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700172
Eino-Ville Talvala97197152012-08-06 14:25:19 -0700173 if (detailLevel > 0) {
174 result = " Request queue contents:\n";
175 write(fd, result.string(), result.size());
176 mRequestQueue.dump(fd, args);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700177
Eino-Ville Talvala97197152012-08-06 14:25:19 -0700178 result = " Frame queue contents:\n";
179 write(fd, result.string(), result.size());
180 mFrameQueue.dump(fd, args);
181 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700182
183 result = " Active streams:\n";
184 write(fd, result.string(), result.size());
185 for (StreamList::iterator s = mStreams.begin(); s != mStreams.end(); s++) {
186 (*s)->dump(fd, args);
187 }
188
189 result = " HAL device dump:\n";
190 write(fd, result.string(), result.size());
191
192 status_t res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800193 res = mHal2Device->ops->dump(mHal2Device, fd);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700194
195 return res;
196}
197
Igor Murashkinbd02dd12013-02-13 15:53:56 -0800198const CameraMetadata& Camera2Device::info() const {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700199 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700200
201 return mDeviceInfo;
202}
203
Jianing Weicb0652e2014-03-12 18:29:36 -0700204status_t Camera2Device::capture(CameraMetadata &request, int64_t* /*lastFrameNumber*/) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700205 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700206 ALOGV("%s: E", __FUNCTION__);
207
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700208 mRequestQueue.enqueue(request.release());
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700209 return OK;
210}
211
Jianing Weicb0652e2014-03-12 18:29:36 -0700212status_t Camera2Device::captureList(const List<const CameraMetadata> &requests,
213 int64_t* /*lastFrameNumber*/) {
Jianing Wei90e59c92014-03-12 18:29:36 -0700214 ATRACE_CALL();
215 ALOGE("%s: Camera2Device burst capture not implemented", __FUNCTION__);
216 return INVALID_OPERATION;
217}
218
Jianing Weicb0652e2014-03-12 18:29:36 -0700219status_t Camera2Device::setStreamingRequest(const CameraMetadata &request,
220 int64_t* /*lastFrameNumber*/) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700221 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700222 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700223 CameraMetadata streamRequest(request);
224 return mRequestQueue.setStreamSlot(streamRequest.release());
225}
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700226
Jianing Weicb0652e2014-03-12 18:29:36 -0700227status_t Camera2Device::setStreamingRequestList(const List<const CameraMetadata> &requests,
228 int64_t* /*lastFrameNumber*/) {
Jianing Wei90e59c92014-03-12 18:29:36 -0700229 ATRACE_CALL();
230 ALOGE("%s, Camera2Device streaming burst not implemented", __FUNCTION__);
231 return INVALID_OPERATION;
232}
233
Jianing Weicb0652e2014-03-12 18:29:36 -0700234status_t Camera2Device::clearStreamingRequest(int64_t* /*lastFrameNumber*/) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700235 ATRACE_CALL();
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700236 return mRequestQueue.setStreamSlot(NULL);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700237}
238
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700239status_t Camera2Device::waitUntilRequestReceived(int32_t requestId, nsecs_t timeout) {
240 ATRACE_CALL();
241 return mRequestQueue.waitForDequeue(requestId, timeout);
242}
243
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700244status_t Camera2Device::createStream(sp<ANativeWindow> consumer,
Zhijun He28c9b6f2014-08-08 12:00:47 -0700245 uint32_t width, uint32_t height, int format, 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,
318 uint32_t *width, uint32_t *height, uint32_t *format) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700319 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700320 ALOGV("%s: E", __FUNCTION__);
321 bool found = false;
322 StreamList::iterator streamI;
323 for (streamI = mStreams.begin();
324 streamI != mStreams.end(); streamI++) {
325 if ((*streamI)->getId() == id) {
326 found = true;
327 break;
328 }
329 }
330 if (!found) {
331 ALOGE("%s: Camera %d: Stream %d does not exist",
332 __FUNCTION__, mId, id);
333 return BAD_VALUE;
334 }
335
336 if (width) *width = (*streamI)->getWidth();
337 if (height) *height = (*streamI)->getHeight();
338 if (format) *format = (*streamI)->getFormat();
339
340 return OK;
341}
342
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -0700343status_t Camera2Device::setStreamTransform(int id,
344 int transform) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700345 ATRACE_CALL();
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -0700346 ALOGV("%s: E", __FUNCTION__);
347 bool found = false;
348 StreamList::iterator streamI;
349 for (streamI = mStreams.begin();
350 streamI != mStreams.end(); streamI++) {
351 if ((*streamI)->getId() == id) {
352 found = true;
353 break;
354 }
355 }
356 if (!found) {
357 ALOGE("%s: Camera %d: Stream %d does not exist",
358 __FUNCTION__, mId, id);
359 return BAD_VALUE;
360 }
361
362 return (*streamI)->setTransform(transform);
363}
364
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700365status_t Camera2Device::deleteStream(int id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700366 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700367 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700368 bool found = false;
369 for (StreamList::iterator streamI = mStreams.begin();
370 streamI != mStreams.end(); streamI++) {
371 if ((*streamI)->getId() == id) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700372 status_t res = (*streamI)->release();
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700373 if (res != OK) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700374 ALOGE("%s: Unable to release stream %d from HAL device: "
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700375 "%s (%d)", __FUNCTION__, id, strerror(-res), res);
376 return res;
377 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700378 mStreams.erase(streamI);
379 found = true;
380 break;
381 }
382 }
383 if (!found) {
384 ALOGE("%s: Camera %d: Unable to find stream %d to delete",
385 __FUNCTION__, mId, id);
386 return BAD_VALUE;
387 }
388 return OK;
389}
390
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700391status_t Camera2Device::deleteReprocessStream(int id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700392 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700393 ALOGV("%s: E", __FUNCTION__);
394 bool found = false;
395 for (ReprocessStreamList::iterator streamI = mReprocessStreams.begin();
396 streamI != mReprocessStreams.end(); streamI++) {
397 if ((*streamI)->getId() == id) {
398 status_t res = (*streamI)->release();
399 if (res != OK) {
400 ALOGE("%s: Unable to release reprocess stream %d from "
401 "HAL device: %s (%d)", __FUNCTION__, id,
402 strerror(-res), res);
403 return res;
404 }
405 mReprocessStreams.erase(streamI);
406 found = true;
407 break;
408 }
409 }
410 if (!found) {
411 ALOGE("%s: Camera %d: Unable to find stream %d to delete",
412 __FUNCTION__, mId, id);
413 return BAD_VALUE;
414 }
415 return OK;
416}
417
418
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700419status_t Camera2Device::createDefaultRequest(int templateId,
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700420 CameraMetadata *request) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700421 ATRACE_CALL();
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700422 status_t err;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700423 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700424 camera_metadata_t *rawRequest;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800425 err = mHal2Device->ops->construct_default_request(
426 mHal2Device, templateId, &rawRequest);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700427 request->acquire(rawRequest);
428 return err;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700429}
430
431status_t Camera2Device::waitUntilDrained() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700432 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700433 static const uint32_t kSleepTime = 50000; // 50 ms
434 static const uint32_t kMaxSleepTime = 10000000; // 10 s
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700435 ALOGV("%s: Camera %d: Starting wait", __FUNCTION__, mId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700436 if (mRequestQueue.getBufferCount() ==
437 CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS) return INVALID_OPERATION;
438
439 // TODO: Set up notifications from HAL, instead of sleeping here
440 uint32_t totalTime = 0;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800441 while (mHal2Device->ops->get_in_progress_count(mHal2Device) > 0) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700442 usleep(kSleepTime);
443 totalTime += kSleepTime;
444 if (totalTime > kMaxSleepTime) {
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700445 ALOGE("%s: Waited %d us, %d requests still in flight", __FUNCTION__,
Alex Rayf0eeb532013-03-17 03:23:18 -0700446 totalTime, mHal2Device->ops->get_in_progress_count(mHal2Device));
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700447 return TIMED_OUT;
448 }
449 }
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700450 ALOGV("%s: Camera %d: HAL is idle", __FUNCTION__, mId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700451 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700452}
453
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700454status_t Camera2Device::setNotifyCallback(NotificationListener *listener) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700455 ATRACE_CALL();
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700456 status_t res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800457 res = mHal2Device->ops->set_notify_callback(mHal2Device, notificationCallback,
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700458 reinterpret_cast<void*>(listener) );
459 if (res != OK) {
460 ALOGE("%s: Unable to set notification callback!", __FUNCTION__);
461 }
462 return res;
463}
464
Eino-Ville Talvala46910bd2013-07-18 19:15:17 -0700465bool Camera2Device::willNotify3A() {
466 return true;
467}
468
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700469void Camera2Device::notificationCallback(int32_t msg_type,
470 int32_t ext1,
471 int32_t ext2,
472 int32_t ext3,
473 void *user) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700474 ATRACE_CALL();
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700475 NotificationListener *listener = reinterpret_cast<NotificationListener*>(user);
476 ALOGV("%s: Notification %d, arguments %d, %d, %d", __FUNCTION__, msg_type,
477 ext1, ext2, ext3);
478 if (listener != NULL) {
479 switch (msg_type) {
480 case CAMERA2_MSG_ERROR:
Jianing Weicb0652e2014-03-12 18:29:36 -0700481 // TODO: This needs to be fixed. ext2 and ext3 need to be considered.
482 listener->notifyError(
483 ((ext1 == CAMERA2_MSG_ERROR_DEVICE)
484 || (ext1 == CAMERA2_MSG_ERROR_HARDWARE)) ?
485 ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE :
486 ICameraDeviceCallbacks::ERROR_CAMERA_SERVICE,
487 CaptureResultExtras());
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700488 break;
489 case CAMERA2_MSG_SHUTTER: {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700490 // TODO: Only needed for camera2 API, which is unsupported
491 // by HAL2 directly.
492 // nsecs_t timestamp = (nsecs_t)ext2 | ((nsecs_t)(ext3) << 32 );
493 // listener->notifyShutter(requestId, timestamp);
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700494 break;
495 }
496 case CAMERA2_MSG_AUTOFOCUS:
497 listener->notifyAutoFocus(ext1, ext2);
498 break;
499 case CAMERA2_MSG_AUTOEXPOSURE:
500 listener->notifyAutoExposure(ext1, ext2);
501 break;
502 case CAMERA2_MSG_AUTOWB:
503 listener->notifyAutoWhitebalance(ext1, ext2);
504 break;
505 default:
506 ALOGE("%s: Unknown notification %d (arguments %d, %d, %d)!",
507 __FUNCTION__, msg_type, ext1, ext2, ext3);
508 }
509 }
510}
511
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -0700512status_t Camera2Device::waitForNextFrame(nsecs_t timeout) {
513 return mFrameQueue.waitForBuffer(timeout);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700514}
515
Jianing Weicb0652e2014-03-12 18:29:36 -0700516status_t Camera2Device::getNextResult(CaptureResult *result) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700517 ATRACE_CALL();
Jianing Weicb0652e2014-03-12 18:29:36 -0700518 ALOGV("%s: get CaptureResult", __FUNCTION__);
519 if (result == NULL) {
520 ALOGE("%s: result pointer is NULL", __FUNCTION__);
521 return BAD_VALUE;
522 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700523 status_t res;
524 camera_metadata_t *rawFrame;
525 res = mFrameQueue.dequeue(&rawFrame);
Jianing Weicb0652e2014-03-12 18:29:36 -0700526 if (rawFrame == NULL) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700527 return NOT_ENOUGH_DATA;
528 } else if (res == OK) {
Jianing Weicb0652e2014-03-12 18:29:36 -0700529 result->mMetadata.acquire(rawFrame);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700530 }
Jianing Weicb0652e2014-03-12 18:29:36 -0700531
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700532 return res;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700533}
534
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700535status_t Camera2Device::triggerAutofocus(uint32_t id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700536 ATRACE_CALL();
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700537 status_t res;
538 ALOGV("%s: Triggering autofocus, id %d", __FUNCTION__, id);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800539 res = mHal2Device->ops->trigger_action(mHal2Device,
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700540 CAMERA2_TRIGGER_AUTOFOCUS, id, 0);
541 if (res != OK) {
542 ALOGE("%s: Error triggering autofocus (id %d)",
543 __FUNCTION__, id);
544 }
545 return res;
546}
547
548status_t Camera2Device::triggerCancelAutofocus(uint32_t id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700549 ATRACE_CALL();
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700550 status_t res;
551 ALOGV("%s: Canceling autofocus, id %d", __FUNCTION__, id);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800552 res = mHal2Device->ops->trigger_action(mHal2Device,
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700553 CAMERA2_TRIGGER_CANCEL_AUTOFOCUS, id, 0);
554 if (res != OK) {
555 ALOGE("%s: Error canceling autofocus (id %d)",
556 __FUNCTION__, id);
557 }
558 return res;
559}
560
561status_t Camera2Device::triggerPrecaptureMetering(uint32_t id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700562 ATRACE_CALL();
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700563 status_t res;
564 ALOGV("%s: Triggering precapture metering, id %d", __FUNCTION__, id);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800565 res = mHal2Device->ops->trigger_action(mHal2Device,
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700566 CAMERA2_TRIGGER_PRECAPTURE_METERING, id, 0);
567 if (res != OK) {
568 ALOGE("%s: Error triggering precapture metering (id %d)",
569 __FUNCTION__, id);
570 }
571 return res;
572}
573
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700574status_t Camera2Device::pushReprocessBuffer(int reprocessStreamId,
575 buffer_handle_t *buffer, wp<BufferReleasedListener> listener) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700576 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700577 ALOGV("%s: E", __FUNCTION__);
578 bool found = false;
579 status_t res = OK;
580 for (ReprocessStreamList::iterator streamI = mReprocessStreams.begin();
581 streamI != mReprocessStreams.end(); streamI++) {
582 if ((*streamI)->getId() == reprocessStreamId) {
583 res = (*streamI)->pushIntoStream(buffer, listener);
584 if (res != OK) {
585 ALOGE("%s: Unable to push buffer to reprocess stream %d: %s (%d)",
586 __FUNCTION__, reprocessStreamId, strerror(-res), res);
587 return res;
588 }
589 found = true;
590 break;
591 }
592 }
593 if (!found) {
594 ALOGE("%s: Camera %d: Unable to find reprocess stream %d",
595 __FUNCTION__, mId, reprocessStreamId);
596 res = BAD_VALUE;
597 }
598 return res;
599}
600
Jianing Weicb0652e2014-03-12 18:29:36 -0700601status_t Camera2Device::flush(int64_t* /*lastFrameNumber*/) {
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -0700602 ATRACE_CALL();
603
604 mRequestQueue.clear();
605 return waitUntilDrained();
606}
607
Zhijun He204e3292014-07-14 17:09:23 -0700608uint32_t Camera2Device::getDeviceVersion() {
609 ATRACE_CALL();
610 return mDeviceVersion;
611}
612
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700613/**
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700614 * Camera2Device::MetadataQueue
615 */
616
617Camera2Device::MetadataQueue::MetadataQueue():
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800618 mHal2Device(NULL),
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700619 mFrameCount(0),
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700620 mLatestRequestId(0),
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700621 mCount(0),
622 mStreamSlotCount(0),
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -0700623 mSignalConsumer(true)
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700624{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700625 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700626 camera2_request_queue_src_ops::dequeue_request = consumer_dequeue;
627 camera2_request_queue_src_ops::request_count = consumer_buffer_count;
628 camera2_request_queue_src_ops::free_request = consumer_free;
629
630 camera2_frame_queue_dst_ops::dequeue_frame = producer_dequeue;
631 camera2_frame_queue_dst_ops::cancel_frame = producer_cancel;
632 camera2_frame_queue_dst_ops::enqueue_frame = producer_enqueue;
633}
634
635Camera2Device::MetadataQueue::~MetadataQueue() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700636 ATRACE_CALL();
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -0700637 clear();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700638}
639
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700640// Connect to camera2 HAL as consumer (input requests/reprocessing)
641status_t Camera2Device::MetadataQueue::setConsumerDevice(camera2_device_t *d) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700642 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700643 status_t res;
644 res = d->ops->set_request_queue_src_ops(d,
645 this);
646 if (res != OK) return res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800647 mHal2Device = d;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700648 return OK;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700649}
650
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700651status_t Camera2Device::MetadataQueue::setProducerDevice(camera2_device_t *d) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700652 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700653 status_t res;
654 res = d->ops->set_frame_queue_dst_ops(d,
655 this);
656 return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700657}
658
659// Real interfaces
660status_t Camera2Device::MetadataQueue::enqueue(camera_metadata_t *buf) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700661 ATRACE_CALL();
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700662 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700663 Mutex::Autolock l(mMutex);
664
665 mCount++;
666 mEntries.push_back(buf);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700667
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700668 return signalConsumerLocked();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700669}
670
671int Camera2Device::MetadataQueue::getBufferCount() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700672 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700673 Mutex::Autolock l(mMutex);
674 if (mStreamSlotCount > 0) {
675 return CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS;
676 }
677 return mCount;
678}
679
680status_t Camera2Device::MetadataQueue::dequeue(camera_metadata_t **buf,
681 bool incrementCount)
682{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700683 ATRACE_CALL();
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700684 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700685 status_t res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700686 Mutex::Autolock l(mMutex);
687
688 if (mCount == 0) {
689 if (mStreamSlotCount == 0) {
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700690 ALOGVV("%s: Empty", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700691 *buf = NULL;
692 mSignalConsumer = true;
693 return OK;
694 }
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700695 ALOGVV("%s: Streaming %d frames to queue", __FUNCTION__,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700696 mStreamSlotCount);
697
698 for (List<camera_metadata_t*>::iterator slotEntry = mStreamSlot.begin();
699 slotEntry != mStreamSlot.end();
700 slotEntry++ ) {
701 size_t entries = get_camera_metadata_entry_count(*slotEntry);
702 size_t dataBytes = get_camera_metadata_data_count(*slotEntry);
703
704 camera_metadata_t *copy =
705 allocate_camera_metadata(entries, dataBytes);
706 append_camera_metadata(copy, *slotEntry);
707 mEntries.push_back(copy);
708 }
709 mCount = mStreamSlotCount;
710 }
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700711 ALOGVV("MetadataQueue: deque (%d buffers)", mCount);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700712 camera_metadata_t *b = *(mEntries.begin());
713 mEntries.erase(mEntries.begin());
714
715 if (incrementCount) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700716 ATRACE_INT("cam2_request", mFrameCount);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700717 camera_metadata_entry_t frameCount;
718 res = find_camera_metadata_entry(b,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700719 ANDROID_REQUEST_FRAME_COUNT,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700720 &frameCount);
721 if (res != OK) {
722 ALOGE("%s: Unable to add frame count: %s (%d)",
723 __FUNCTION__, strerror(-res), res);
724 } else {
725 *frameCount.data.i32 = mFrameCount;
726 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700727 mFrameCount++;
728 }
729
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700730 // Check for request ID, and if present, signal waiters.
731 camera_metadata_entry_t requestId;
732 res = find_camera_metadata_entry(b,
733 ANDROID_REQUEST_ID,
734 &requestId);
735 if (res == OK) {
736 mLatestRequestId = requestId.data.i32[0];
737 mNewRequestId.signal();
738 }
739
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700740 *buf = b;
741 mCount--;
742
743 return OK;
744}
745
746status_t Camera2Device::MetadataQueue::waitForBuffer(nsecs_t timeout)
747{
748 Mutex::Autolock l(mMutex);
749 status_t res;
750 while (mCount == 0) {
751 res = notEmpty.waitRelative(mMutex,timeout);
752 if (res != OK) return res;
753 }
754 return OK;
755}
756
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700757status_t Camera2Device::MetadataQueue::waitForDequeue(int32_t id,
758 nsecs_t timeout) {
759 Mutex::Autolock l(mMutex);
760 status_t res;
761 while (mLatestRequestId != id) {
762 nsecs_t startTime = systemTime();
763
764 res = mNewRequestId.waitRelative(mMutex, timeout);
765 if (res != OK) return res;
766
767 timeout -= (systemTime() - startTime);
768 }
769
770 return OK;
771}
772
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700773status_t Camera2Device::MetadataQueue::setStreamSlot(camera_metadata_t *buf)
774{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700775 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700776 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700777 Mutex::Autolock l(mMutex);
778 if (buf == NULL) {
779 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
780 mStreamSlotCount = 0;
781 return OK;
782 }
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700783 camera_metadata_t *buf2 = clone_camera_metadata(buf);
784 if (!buf2) {
785 ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__);
786 return NO_MEMORY;
787 }
788
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700789 if (mStreamSlotCount > 1) {
790 List<camera_metadata_t*>::iterator deleter = ++mStreamSlot.begin();
791 freeBuffers(++mStreamSlot.begin(), mStreamSlot.end());
792 mStreamSlotCount = 1;
793 }
794 if (mStreamSlotCount == 1) {
795 free_camera_metadata( *(mStreamSlot.begin()) );
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700796 *(mStreamSlot.begin()) = buf2;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700797 } else {
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700798 mStreamSlot.push_front(buf2);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700799 mStreamSlotCount = 1;
800 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700801 return signalConsumerLocked();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700802}
803
804status_t Camera2Device::MetadataQueue::setStreamSlot(
805 const List<camera_metadata_t*> &bufs)
806{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700807 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700808 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700809 Mutex::Autolock l(mMutex);
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700810
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700811 if (mStreamSlotCount > 0) {
812 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
813 }
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700814 mStreamSlotCount = 0;
815 for (List<camera_metadata_t*>::const_iterator r = bufs.begin();
816 r != bufs.end(); r++) {
817 camera_metadata_t *r2 = clone_camera_metadata(*r);
818 if (!r2) {
819 ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__);
820 return NO_MEMORY;
821 }
822 mStreamSlot.push_back(r2);
823 mStreamSlotCount++;
824 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700825 return signalConsumerLocked();
826}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700827
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -0700828status_t Camera2Device::MetadataQueue::clear()
829{
830 ATRACE_CALL();
831 ALOGV("%s: E", __FUNCTION__);
832
833 Mutex::Autolock l(mMutex);
834
835 // Clear streaming slot
836 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
837 mStreamSlotCount = 0;
838
839 // Clear request queue
840 freeBuffers(mEntries.begin(), mEntries.end());
841 mCount = 0;
842 return OK;
843}
844
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700845status_t Camera2Device::MetadataQueue::dump(int fd,
Igor Murashkinebe3f692012-10-12 16:56:11 -0700846 const Vector<String16>& /*args*/) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700847 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700848 String8 result;
849 status_t notLocked;
850 notLocked = mMutex.tryLock();
851 if (notLocked) {
852 result.append(" (Unable to lock queue mutex)\n");
853 }
854 result.appendFormat(" Current frame number: %d\n", mFrameCount);
855 if (mStreamSlotCount == 0) {
856 result.append(" Stream slot: Empty\n");
857 write(fd, result.string(), result.size());
858 } else {
Kévin PETIT377b2ec2014-02-03 12:35:36 +0000859 result.appendFormat(" Stream slot: %zu entries\n",
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700860 mStreamSlot.size());
861 int i = 0;
862 for (List<camera_metadata_t*>::iterator r = mStreamSlot.begin();
863 r != mStreamSlot.end(); r++) {
864 result = String8::format(" Stream slot buffer %d:\n", i);
865 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700866 dump_indented_camera_metadata(*r, fd, 2, 10);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700867 i++;
868 }
869 }
870 if (mEntries.size() == 0) {
871 result = " Main queue is empty\n";
872 write(fd, result.string(), result.size());
873 } else {
Kévin PETIT377b2ec2014-02-03 12:35:36 +0000874 result = String8::format(" Main queue has %zu entries:\n",
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700875 mEntries.size());
876 int i = 0;
877 for (List<camera_metadata_t*>::iterator r = mEntries.begin();
878 r != mEntries.end(); r++) {
879 result = String8::format(" Queue entry %d:\n", i);
880 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700881 dump_indented_camera_metadata(*r, fd, 2, 10);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700882 i++;
883 }
884 }
885
886 if (notLocked == 0) {
887 mMutex.unlock();
888 }
889
890 return OK;
891}
892
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700893status_t Camera2Device::MetadataQueue::signalConsumerLocked() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700894 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700895 status_t res = OK;
896 notEmpty.signal();
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800897 if (mSignalConsumer && mHal2Device != NULL) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700898 mSignalConsumer = false;
899
900 mMutex.unlock();
901 ALOGV("%s: Signaling consumer", __FUNCTION__);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800902 res = mHal2Device->ops->notify_request_queue_not_empty(mHal2Device);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700903 mMutex.lock();
904 }
905 return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700906}
907
908status_t Camera2Device::MetadataQueue::freeBuffers(
909 List<camera_metadata_t*>::iterator start,
910 List<camera_metadata_t*>::iterator end)
911{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700912 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700913 while (start != end) {
914 free_camera_metadata(*start);
915 start = mStreamSlot.erase(start);
916 }
917 return OK;
918}
919
920Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
921 const camera2_request_queue_src_ops_t *q)
922{
923 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
924 return const_cast<MetadataQueue*>(cmq);
925}
926
927Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
928 const camera2_frame_queue_dst_ops_t *q)
929{
930 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
931 return const_cast<MetadataQueue*>(cmq);
932}
933
934int Camera2Device::MetadataQueue::consumer_buffer_count(
935 const camera2_request_queue_src_ops_t *q)
936{
937 MetadataQueue *queue = getInstance(q);
938 return queue->getBufferCount();
939}
940
941int Camera2Device::MetadataQueue::consumer_dequeue(
942 const camera2_request_queue_src_ops_t *q,
943 camera_metadata_t **buffer)
944{
945 MetadataQueue *queue = getInstance(q);
946 return queue->dequeue(buffer, true);
947}
948
949int Camera2Device::MetadataQueue::consumer_free(
950 const camera2_request_queue_src_ops_t *q,
951 camera_metadata_t *old_buffer)
952{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700953 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700954 MetadataQueue *queue = getInstance(q);
Igor Murashkinebe3f692012-10-12 16:56:11 -0700955 (void)queue;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700956 free_camera_metadata(old_buffer);
957 return OK;
958}
959
960int Camera2Device::MetadataQueue::producer_dequeue(
Igor Murashkinebe3f692012-10-12 16:56:11 -0700961 const camera2_frame_queue_dst_ops_t * /*q*/,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700962 size_t entries, size_t bytes,
963 camera_metadata_t **buffer)
964{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700965 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700966 camera_metadata_t *new_buffer =
967 allocate_camera_metadata(entries, bytes);
968 if (new_buffer == NULL) return NO_MEMORY;
969 *buffer = new_buffer;
970 return OK;
971}
972
973int Camera2Device::MetadataQueue::producer_cancel(
Igor Murashkinebe3f692012-10-12 16:56:11 -0700974 const camera2_frame_queue_dst_ops_t * /*q*/,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700975 camera_metadata_t *old_buffer)
976{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700977 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700978 free_camera_metadata(old_buffer);
979 return OK;
980}
981
982int Camera2Device::MetadataQueue::producer_enqueue(
983 const camera2_frame_queue_dst_ops_t *q,
984 camera_metadata_t *filled_buffer)
985{
986 MetadataQueue *queue = getInstance(q);
987 return queue->enqueue(filled_buffer);
988}
989
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700990/**
991 * Camera2Device::StreamAdapter
992 */
993
994#ifndef container_of
995#define container_of(ptr, type, member) \
996 (type *)((char*)(ptr) - offsetof(type, member))
997#endif
998
999Camera2Device::StreamAdapter::StreamAdapter(camera2_device_t *d):
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001000 mState(RELEASED),
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001001 mHal2Device(d),
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001002 mId(-1),
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001003 mWidth(0), mHeight(0), mFormat(0), mSize(0), mUsage(0),
1004 mMaxProducerBuffers(0), mMaxConsumerBuffers(0),
1005 mTotalBuffers(0),
1006 mFormatRequested(0),
1007 mActiveBuffers(0),
1008 mFrameCount(0),
1009 mLastTimestamp(0)
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001010{
1011 camera2_stream_ops::dequeue_buffer = dequeue_buffer;
1012 camera2_stream_ops::enqueue_buffer = enqueue_buffer;
1013 camera2_stream_ops::cancel_buffer = cancel_buffer;
1014 camera2_stream_ops::set_crop = set_crop;
1015}
1016
1017Camera2Device::StreamAdapter::~StreamAdapter() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001018 ATRACE_CALL();
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001019 if (mState != RELEASED) {
1020 release();
1021 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001022}
1023
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001024status_t Camera2Device::StreamAdapter::connectToDevice(
1025 sp<ANativeWindow> consumer,
1026 uint32_t width, uint32_t height, int format, size_t size) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001027 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001028 status_t res;
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -07001029 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001030
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001031 if (mState != RELEASED) return INVALID_OPERATION;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001032 if (consumer == NULL) {
1033 ALOGE("%s: Null consumer passed to stream adapter", __FUNCTION__);
1034 return BAD_VALUE;
1035 }
1036
Colin Crosse5729fa2014-03-21 15:04:25 -07001037 ALOGV("%s: New stream parameters %d x %d, format 0x%x, size %zu",
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001038 __FUNCTION__, width, height, format, size);
1039
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001040 mConsumerInterface = consumer;
1041 mWidth = width;
1042 mHeight = height;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001043 mSize = (format == HAL_PIXEL_FORMAT_BLOB) ? size : 0;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001044 mFormatRequested = format;
1045
1046 // Allocate device-side stream interface
1047
1048 uint32_t id;
1049 uint32_t formatActual;
1050 uint32_t usage;
1051 uint32_t maxBuffers = 2;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001052 res = mHal2Device->ops->allocate_stream(mHal2Device,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001053 mWidth, mHeight, mFormatRequested, getStreamOps(),
1054 &id, &formatActual, &usage, &maxBuffers);
1055 if (res != OK) {
1056 ALOGE("%s: Device stream allocation failed: %s (%d)",
1057 __FUNCTION__, strerror(-res), res);
1058 return res;
1059 }
1060
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001061 ALOGV("%s: Allocated stream id %d, actual format 0x%x, "
1062 "usage 0x%x, producer wants %d buffers", __FUNCTION__,
1063 id, formatActual, usage, maxBuffers);
1064
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001065 mId = id;
1066 mFormat = formatActual;
1067 mUsage = usage;
1068 mMaxProducerBuffers = maxBuffers;
1069
1070 mState = ALLOCATED;
1071
1072 // Configure consumer-side ANativeWindow interface
1073 res = native_window_api_connect(mConsumerInterface.get(),
1074 NATIVE_WINDOW_API_CAMERA);
1075 if (res != OK) {
1076 ALOGE("%s: Unable to connect to native window for stream %d",
1077 __FUNCTION__, mId);
1078
1079 return res;
1080 }
1081
1082 mState = CONNECTED;
1083
1084 res = native_window_set_usage(mConsumerInterface.get(), mUsage);
1085 if (res != OK) {
1086 ALOGE("%s: Unable to configure usage %08x for stream %d",
1087 __FUNCTION__, mUsage, mId);
1088 return res;
1089 }
1090
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001091 res = native_window_set_scaling_mode(mConsumerInterface.get(),
1092 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
1093 if (res != OK) {
1094 ALOGE("%s: Unable to configure stream scaling: %s (%d)",
1095 __FUNCTION__, strerror(-res), res);
1096 return res;
1097 }
1098
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001099 res = setTransform(0);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001100 if (res != OK) {
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001101 return res;
1102 }
1103
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001104 if (mFormat == HAL_PIXEL_FORMAT_BLOB) {
Eino-Ville Talvala7d70c5e2014-07-24 18:10:23 -07001105 res = native_window_set_buffers_dimensions(mConsumerInterface.get(),
1106 mSize, 1);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001107 if (res != OK) {
Eino-Ville Talvala7d70c5e2014-07-24 18:10:23 -07001108 ALOGE("%s: Unable to configure compressed stream buffer dimensions"
Colin Crosse5729fa2014-03-21 15:04:25 -07001109 " %d x %d, size %zu for stream %d",
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001110 __FUNCTION__, mWidth, mHeight, mSize, mId);
1111 return res;
1112 }
1113 } else {
Eino-Ville Talvala7d70c5e2014-07-24 18:10:23 -07001114 res = native_window_set_buffers_dimensions(mConsumerInterface.get(),
1115 mWidth, mHeight);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001116 if (res != OK) {
Eino-Ville Talvala7d70c5e2014-07-24 18:10:23 -07001117 ALOGE("%s: Unable to configure stream buffer dimensions"
1118 " %d x %d for stream %d",
1119 __FUNCTION__, mWidth, mHeight, mId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001120 return res;
1121 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001122 }
1123
Eino-Ville Talvala7d70c5e2014-07-24 18:10:23 -07001124 res = native_window_set_buffers_format(mConsumerInterface.get(), mFormat);
1125 if (res != OK) {
1126 ALOGE("%s: Unable to configure stream buffer format"
1127 " %#x for stream %d",
1128 __FUNCTION__, mFormat, mId);
1129 return res;
1130 }
1131
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001132 int maxConsumerBuffers;
1133 res = mConsumerInterface->query(mConsumerInterface.get(),
1134 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &maxConsumerBuffers);
1135 if (res != OK) {
1136 ALOGE("%s: Unable to query consumer undequeued"
1137 " buffer count for stream %d", __FUNCTION__, mId);
1138 return res;
1139 }
1140 mMaxConsumerBuffers = maxConsumerBuffers;
1141
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001142 ALOGV("%s: Consumer wants %d buffers", __FUNCTION__,
1143 mMaxConsumerBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001144
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001145 mTotalBuffers = mMaxConsumerBuffers + mMaxProducerBuffers;
1146 mActiveBuffers = 0;
1147 mFrameCount = 0;
1148 mLastTimestamp = 0;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001149
1150 res = native_window_set_buffer_count(mConsumerInterface.get(),
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001151 mTotalBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001152 if (res != OK) {
1153 ALOGE("%s: Unable to set buffer count for stream %d",
1154 __FUNCTION__, mId);
1155 return res;
1156 }
1157
1158 // Register allocated buffers with HAL device
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001159 buffer_handle_t *buffers = new buffer_handle_t[mTotalBuffers];
1160 ANativeWindowBuffer **anwBuffers = new ANativeWindowBuffer*[mTotalBuffers];
1161 uint32_t bufferIdx = 0;
1162 for (; bufferIdx < mTotalBuffers; bufferIdx++) {
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001163 res = native_window_dequeue_buffer_and_wait(mConsumerInterface.get(),
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001164 &anwBuffers[bufferIdx]);
1165 if (res != OK) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001166 ALOGE("%s: Unable to dequeue buffer %d for initial registration for "
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001167 "stream %d", __FUNCTION__, bufferIdx, mId);
1168 goto cleanUpBuffers;
1169 }
1170
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001171 buffers[bufferIdx] = anwBuffers[bufferIdx]->handle;
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001172 ALOGV("%s: Buffer %p allocated", __FUNCTION__, (void*)buffers[bufferIdx]);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001173 }
1174
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001175 ALOGV("%s: Registering %d buffers with camera HAL", __FUNCTION__, mTotalBuffers);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001176 res = mHal2Device->ops->register_stream_buffers(mHal2Device,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001177 mId,
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001178 mTotalBuffers,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001179 buffers);
1180 if (res != OK) {
1181 ALOGE("%s: Unable to register buffers with HAL device for stream %d",
1182 __FUNCTION__, mId);
1183 } else {
1184 mState = ACTIVE;
1185 }
1186
1187cleanUpBuffers:
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001188 ALOGV("%s: Cleaning up %d buffers", __FUNCTION__, bufferIdx);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001189 for (uint32_t i = 0; i < bufferIdx; i++) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001190 res = mConsumerInterface->cancelBuffer(mConsumerInterface.get(),
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001191 anwBuffers[i], -1);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001192 if (res != OK) {
1193 ALOGE("%s: Unable to cancel buffer %d after registration",
1194 __FUNCTION__, i);
1195 }
1196 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001197 delete[] anwBuffers;
1198 delete[] buffers;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001199
1200 return res;
1201}
1202
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001203status_t Camera2Device::StreamAdapter::release() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001204 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001205 status_t res;
Eino-Ville Talvala02f84572013-04-23 15:16:57 -07001206 ALOGV("%s: Releasing stream %d (%d x %d, format %d)", __FUNCTION__, mId,
1207 mWidth, mHeight, mFormat);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001208 if (mState >= ALLOCATED) {
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001209 res = mHal2Device->ops->release_stream(mHal2Device, mId);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001210 if (res != OK) {
1211 ALOGE("%s: Unable to release stream %d",
1212 __FUNCTION__, mId);
1213 return res;
1214 }
1215 }
1216 if (mState >= CONNECTED) {
1217 res = native_window_api_disconnect(mConsumerInterface.get(),
1218 NATIVE_WINDOW_API_CAMERA);
Igor Murashkina1e5dcc2012-10-02 15:21:31 -07001219
1220 /* this is not an error. if client calling process dies,
1221 the window will also die and all calls to it will return
1222 DEAD_OBJECT, thus it's already "disconnected" */
1223 if (res == DEAD_OBJECT) {
1224 ALOGW("%s: While disconnecting stream %d from native window, the"
1225 " native window died from under us", __FUNCTION__, mId);
1226 }
1227 else if (res != OK) {
1228 ALOGE("%s: Unable to disconnect stream %d from native window (error %d %s)",
1229 __FUNCTION__, mId, res, strerror(-res));
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001230 return res;
1231 }
1232 }
1233 mId = -1;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001234 mState = RELEASED;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001235 return OK;
1236}
1237
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001238status_t Camera2Device::StreamAdapter::setTransform(int transform) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001239 ATRACE_CALL();
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001240 status_t res;
1241 if (mState < CONNECTED) {
1242 ALOGE("%s: Cannot set transform on unconnected stream", __FUNCTION__);
1243 return INVALID_OPERATION;
1244 }
1245 res = native_window_set_buffers_transform(mConsumerInterface.get(),
1246 transform);
1247 if (res != OK) {
1248 ALOGE("%s: Unable to configure stream transform to %x: %s (%d)",
1249 __FUNCTION__, transform, strerror(-res), res);
1250 }
1251 return res;
1252}
1253
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001254status_t Camera2Device::StreamAdapter::dump(int fd,
Igor Murashkinebe3f692012-10-12 16:56:11 -07001255 const Vector<String16>& /*args*/) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001256 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001257 String8 result = String8::format(" Stream %d: %d x %d, format 0x%x\n",
1258 mId, mWidth, mHeight, mFormat);
Kévin PETIT377b2ec2014-02-03 12:35:36 +00001259 result.appendFormat(" size %zu, usage 0x%x, requested format 0x%x\n",
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001260 mSize, mUsage, mFormatRequested);
1261 result.appendFormat(" total buffers: %d, dequeued buffers: %d\n",
1262 mTotalBuffers, mActiveBuffers);
Kévin PETIT377b2ec2014-02-03 12:35:36 +00001263 result.appendFormat(" frame count: %d, last timestamp %" PRId64 "\n",
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001264 mFrameCount, mLastTimestamp);
1265 write(fd, result.string(), result.size());
1266 return OK;
1267}
1268
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001269const camera2_stream_ops *Camera2Device::StreamAdapter::getStreamOps() {
1270 return static_cast<camera2_stream_ops *>(this);
1271}
1272
1273ANativeWindow* Camera2Device::StreamAdapter::toANW(
1274 const camera2_stream_ops_t *w) {
1275 return static_cast<const StreamAdapter*>(w)->mConsumerInterface.get();
1276}
1277
1278int Camera2Device::StreamAdapter::dequeue_buffer(const camera2_stream_ops_t *w,
1279 buffer_handle_t** buffer) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001280 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001281 int res;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001282 StreamAdapter* stream =
1283 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
1284 if (stream->mState != ACTIVE) {
1285 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001286 return INVALID_OPERATION;
1287 }
1288
1289 ANativeWindow *a = toANW(w);
1290 ANativeWindowBuffer* anb;
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001291 res = native_window_dequeue_buffer_and_wait(a, &anb);
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001292 if (res != OK) {
1293 ALOGE("Stream %d dequeue: Error from native_window: %s (%d)", stream->mId,
1294 strerror(-res), res);
1295 return res;
1296 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001297
1298 *buffer = &(anb->handle);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001299 stream->mActiveBuffers++;
1300
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001301 ALOGVV("Stream %d dequeue: Buffer %p dequeued", stream->mId, (void*)(**buffer));
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001302 return res;
1303}
1304
1305int Camera2Device::StreamAdapter::enqueue_buffer(const camera2_stream_ops_t* w,
1306 int64_t timestamp,
1307 buffer_handle_t* buffer) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001308 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001309 StreamAdapter *stream =
1310 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001311 stream->mFrameCount++;
1312 ALOGVV("Stream %d enqueue: Frame %d (%p) captured at %lld ns",
James Donga289bf62012-09-05 16:46:36 -07001313 stream->mId, stream->mFrameCount, (void*)(*buffer), timestamp);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001314 int state = stream->mState;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001315 if (state != ACTIVE) {
1316 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1317 return INVALID_OPERATION;
1318 }
1319 ANativeWindow *a = toANW(w);
1320 status_t err;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001321
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001322 err = native_window_set_buffers_timestamp(a, timestamp);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001323 if (err != OK) {
1324 ALOGE("%s: Error setting timestamp on native window: %s (%d)",
1325 __FUNCTION__, strerror(-err), err);
1326 return err;
1327 }
1328 err = a->queueBuffer(a,
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001329 container_of(buffer, ANativeWindowBuffer, handle), -1);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001330 if (err != OK) {
1331 ALOGE("%s: Error queueing buffer to native window: %s (%d)",
1332 __FUNCTION__, strerror(-err), err);
James Dong31d377b2012-08-09 17:43:46 -07001333 return err;
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001334 }
James Dong31d377b2012-08-09 17:43:46 -07001335
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001336 stream->mActiveBuffers--;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001337 stream->mLastTimestamp = timestamp;
James Dong31d377b2012-08-09 17:43:46 -07001338 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001339}
1340
1341int Camera2Device::StreamAdapter::cancel_buffer(const camera2_stream_ops_t* w,
1342 buffer_handle_t* buffer) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001343 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001344 StreamAdapter *stream =
1345 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001346 ALOGVV("Stream %d cancel: Buffer %p",
1347 stream->mId, (void*)(*buffer));
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001348 if (stream->mState != ACTIVE) {
1349 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001350 return INVALID_OPERATION;
1351 }
James Dong31d377b2012-08-09 17:43:46 -07001352
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001353 ANativeWindow *a = toANW(w);
James Dong31d377b2012-08-09 17:43:46 -07001354 int err = a->cancelBuffer(a,
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001355 container_of(buffer, ANativeWindowBuffer, handle), -1);
James Dong31d377b2012-08-09 17:43:46 -07001356 if (err != OK) {
1357 ALOGE("%s: Error canceling buffer to native window: %s (%d)",
1358 __FUNCTION__, strerror(-err), err);
1359 return err;
1360 }
1361
1362 stream->mActiveBuffers--;
1363 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001364}
1365
1366int Camera2Device::StreamAdapter::set_crop(const camera2_stream_ops_t* w,
1367 int left, int top, int right, int bottom) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001368 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001369 int state = static_cast<const StreamAdapter*>(w)->mState;
1370 if (state != ACTIVE) {
1371 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1372 return INVALID_OPERATION;
1373 }
1374 ANativeWindow *a = toANW(w);
1375 android_native_rect_t crop = { left, top, right, bottom };
1376 return native_window_set_crop(a, &crop);
1377}
1378
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001379/**
1380 * Camera2Device::ReprocessStreamAdapter
1381 */
1382
1383#ifndef container_of
1384#define container_of(ptr, type, member) \
1385 (type *)((char*)(ptr) - offsetof(type, member))
1386#endif
1387
1388Camera2Device::ReprocessStreamAdapter::ReprocessStreamAdapter(camera2_device_t *d):
1389 mState(RELEASED),
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001390 mHal2Device(d),
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001391 mId(-1),
1392 mWidth(0), mHeight(0), mFormat(0),
1393 mActiveBuffers(0),
1394 mFrameCount(0)
1395{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001396 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001397 camera2_stream_in_ops::acquire_buffer = acquire_buffer;
1398 camera2_stream_in_ops::release_buffer = release_buffer;
1399}
1400
1401Camera2Device::ReprocessStreamAdapter::~ReprocessStreamAdapter() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001402 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001403 if (mState != RELEASED) {
1404 release();
1405 }
1406}
1407
1408status_t Camera2Device::ReprocessStreamAdapter::connectToDevice(
1409 const sp<StreamAdapter> &outputStream) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001410 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001411 status_t res;
1412 ALOGV("%s: E", __FUNCTION__);
1413
1414 if (mState != RELEASED) return INVALID_OPERATION;
1415 if (outputStream == NULL) {
1416 ALOGE("%s: Null base stream passed to reprocess stream adapter",
1417 __FUNCTION__);
1418 return BAD_VALUE;
1419 }
1420
1421 mBaseStream = outputStream;
1422 mWidth = outputStream->getWidth();
1423 mHeight = outputStream->getHeight();
1424 mFormat = outputStream->getFormat();
1425
1426 ALOGV("%s: New reprocess stream parameters %d x %d, format 0x%x",
1427 __FUNCTION__, mWidth, mHeight, mFormat);
1428
1429 // Allocate device-side stream interface
1430
1431 uint32_t id;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001432 res = mHal2Device->ops->allocate_reprocess_stream_from_stream(mHal2Device,
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001433 outputStream->getId(), getStreamOps(),
1434 &id);
1435 if (res != OK) {
1436 ALOGE("%s: Device reprocess stream allocation failed: %s (%d)",
1437 __FUNCTION__, strerror(-res), res);
1438 return res;
1439 }
1440
1441 ALOGV("%s: Allocated reprocess stream id %d based on stream %d",
1442 __FUNCTION__, id, outputStream->getId());
1443
1444 mId = id;
1445
1446 mState = ACTIVE;
1447
1448 return OK;
1449}
1450
1451status_t Camera2Device::ReprocessStreamAdapter::release() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001452 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001453 status_t res;
1454 ALOGV("%s: Releasing stream %d", __FUNCTION__, mId);
1455 if (mState >= ACTIVE) {
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001456 res = mHal2Device->ops->release_reprocess_stream(mHal2Device, mId);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001457 if (res != OK) {
1458 ALOGE("%s: Unable to release stream %d",
1459 __FUNCTION__, mId);
1460 return res;
1461 }
1462 }
1463
1464 List<QueueEntry>::iterator s;
1465 for (s = mQueue.begin(); s != mQueue.end(); s++) {
1466 sp<BufferReleasedListener> listener = s->releaseListener.promote();
1467 if (listener != 0) listener->onBufferReleased(s->handle);
1468 }
1469 for (s = mInFlightQueue.begin(); s != mInFlightQueue.end(); s++) {
1470 sp<BufferReleasedListener> listener = s->releaseListener.promote();
1471 if (listener != 0) listener->onBufferReleased(s->handle);
1472 }
1473 mQueue.clear();
1474 mInFlightQueue.clear();
1475
1476 mState = RELEASED;
1477 return OK;
1478}
1479
1480status_t Camera2Device::ReprocessStreamAdapter::pushIntoStream(
1481 buffer_handle_t *handle, const wp<BufferReleasedListener> &releaseListener) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001482 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001483 // TODO: Some error checking here would be nice
1484 ALOGV("%s: Pushing buffer %p to stream", __FUNCTION__, (void*)(*handle));
1485
1486 QueueEntry entry;
1487 entry.handle = handle;
1488 entry.releaseListener = releaseListener;
1489 mQueue.push_back(entry);
1490 return OK;
1491}
1492
1493status_t Camera2Device::ReprocessStreamAdapter::dump(int fd,
Igor Murashkinebe3f692012-10-12 16:56:11 -07001494 const Vector<String16>& /*args*/) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001495 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001496 String8 result =
1497 String8::format(" Reprocess stream %d: %d x %d, fmt 0x%x\n",
1498 mId, mWidth, mHeight, mFormat);
1499 result.appendFormat(" acquired buffers: %d\n",
1500 mActiveBuffers);
1501 result.appendFormat(" frame count: %d\n",
1502 mFrameCount);
1503 write(fd, result.string(), result.size());
1504 return OK;
1505}
1506
1507const camera2_stream_in_ops *Camera2Device::ReprocessStreamAdapter::getStreamOps() {
1508 return static_cast<camera2_stream_in_ops *>(this);
1509}
1510
1511int Camera2Device::ReprocessStreamAdapter::acquire_buffer(
1512 const camera2_stream_in_ops_t *w,
1513 buffer_handle_t** buffer) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001514 ATRACE_CALL();
Igor Murashkinebe3f692012-10-12 16:56:11 -07001515
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001516 ReprocessStreamAdapter* stream =
1517 const_cast<ReprocessStreamAdapter*>(
1518 static_cast<const ReprocessStreamAdapter*>(w));
1519 if (stream->mState != ACTIVE) {
1520 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
1521 return INVALID_OPERATION;
1522 }
1523
1524 if (stream->mQueue.empty()) {
1525 *buffer = NULL;
1526 return OK;
1527 }
1528
1529 QueueEntry &entry = *(stream->mQueue.begin());
1530
1531 *buffer = entry.handle;
1532
1533 stream->mInFlightQueue.push_back(entry);
1534 stream->mQueue.erase(stream->mQueue.begin());
1535
1536 stream->mActiveBuffers++;
1537
1538 ALOGV("Stream %d acquire: Buffer %p acquired", stream->mId,
1539 (void*)(**buffer));
1540 return OK;
1541}
1542
1543int Camera2Device::ReprocessStreamAdapter::release_buffer(
1544 const camera2_stream_in_ops_t* w,
1545 buffer_handle_t* buffer) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001546 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001547 ReprocessStreamAdapter *stream =
1548 const_cast<ReprocessStreamAdapter*>(
1549 static_cast<const ReprocessStreamAdapter*>(w) );
1550 stream->mFrameCount++;
1551 ALOGV("Reprocess stream %d release: Frame %d (%p)",
1552 stream->mId, stream->mFrameCount, (void*)*buffer);
1553 int state = stream->mState;
1554 if (state != ACTIVE) {
1555 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1556 return INVALID_OPERATION;
1557 }
1558 stream->mActiveBuffers--;
1559
1560 List<QueueEntry>::iterator s;
1561 for (s = stream->mInFlightQueue.begin(); s != stream->mInFlightQueue.end(); s++) {
1562 if ( s->handle == buffer ) break;
1563 }
1564 if (s == stream->mInFlightQueue.end()) {
1565 ALOGE("%s: Can't find buffer %p in in-flight list!", __FUNCTION__,
1566 buffer);
1567 return INVALID_OPERATION;
1568 }
1569
1570 sp<BufferReleasedListener> listener = s->releaseListener.promote();
1571 if (listener != 0) {
1572 listener->onBufferReleased(s->handle);
1573 } else {
1574 ALOGE("%s: Can't free buffer - missing listener", __FUNCTION__);
1575 }
1576 stream->mInFlightQueue.erase(s);
1577
1578 return OK;
1579}
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001580
1581}; // namespace android