blob: 8c2520e3b1458cec73635a9a796854a3b96a51b5 [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,
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700245 uint32_t width, uint32_t height, int format, size_t size, 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);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700251
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700252 res = stream->connectToDevice(consumer, width, height, format, size);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700253 if (res != OK) {
254 ALOGE("%s: Camera %d: Unable to create stream (%d x %d, format %x):"
255 "%s (%d)",
256 __FUNCTION__, mId, width, height, format, strerror(-res), res);
257 return res;
258 }
259
260 *id = stream->getId();
261
262 mStreams.push_back(stream);
263 return OK;
264}
265
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700266status_t Camera2Device::createReprocessStreamFromStream(int outputId, int *id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700267 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700268 status_t res;
269 ALOGV("%s: E", __FUNCTION__);
270
271 bool found = false;
272 StreamList::iterator streamI;
273 for (streamI = mStreams.begin();
274 streamI != mStreams.end(); streamI++) {
275 if ((*streamI)->getId() == outputId) {
276 found = true;
277 break;
278 }
279 }
280 if (!found) {
281 ALOGE("%s: Camera %d: Output stream %d doesn't exist; can't create "
282 "reprocess stream from it!", __FUNCTION__, mId, outputId);
283 return BAD_VALUE;
284 }
285
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800286 sp<ReprocessStreamAdapter> stream = new ReprocessStreamAdapter(mHal2Device);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700287
288 res = stream->connectToDevice((*streamI));
289 if (res != OK) {
290 ALOGE("%s: Camera %d: Unable to create reprocessing stream from "\
291 "stream %d: %s (%d)", __FUNCTION__, mId, outputId,
292 strerror(-res), res);
293 return res;
294 }
295
296 *id = stream->getId();
297
298 mReprocessStreams.push_back(stream);
299 return OK;
300}
301
302
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700303status_t Camera2Device::getStreamInfo(int id,
304 uint32_t *width, uint32_t *height, uint32_t *format) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700305 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700306 ALOGV("%s: E", __FUNCTION__);
307 bool found = false;
308 StreamList::iterator streamI;
309 for (streamI = mStreams.begin();
310 streamI != mStreams.end(); streamI++) {
311 if ((*streamI)->getId() == id) {
312 found = true;
313 break;
314 }
315 }
316 if (!found) {
317 ALOGE("%s: Camera %d: Stream %d does not exist",
318 __FUNCTION__, mId, id);
319 return BAD_VALUE;
320 }
321
322 if (width) *width = (*streamI)->getWidth();
323 if (height) *height = (*streamI)->getHeight();
324 if (format) *format = (*streamI)->getFormat();
325
326 return OK;
327}
328
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -0700329status_t Camera2Device::setStreamTransform(int id,
330 int transform) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700331 ATRACE_CALL();
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -0700332 ALOGV("%s: E", __FUNCTION__);
333 bool found = false;
334 StreamList::iterator streamI;
335 for (streamI = mStreams.begin();
336 streamI != mStreams.end(); streamI++) {
337 if ((*streamI)->getId() == id) {
338 found = true;
339 break;
340 }
341 }
342 if (!found) {
343 ALOGE("%s: Camera %d: Stream %d does not exist",
344 __FUNCTION__, mId, id);
345 return BAD_VALUE;
346 }
347
348 return (*streamI)->setTransform(transform);
349}
350
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700351status_t Camera2Device::deleteStream(int id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700352 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700353 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700354 bool found = false;
355 for (StreamList::iterator streamI = mStreams.begin();
356 streamI != mStreams.end(); streamI++) {
357 if ((*streamI)->getId() == id) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700358 status_t res = (*streamI)->release();
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700359 if (res != OK) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700360 ALOGE("%s: Unable to release stream %d from HAL device: "
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700361 "%s (%d)", __FUNCTION__, id, strerror(-res), res);
362 return res;
363 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700364 mStreams.erase(streamI);
365 found = true;
366 break;
367 }
368 }
369 if (!found) {
370 ALOGE("%s: Camera %d: Unable to find stream %d to delete",
371 __FUNCTION__, mId, id);
372 return BAD_VALUE;
373 }
374 return OK;
375}
376
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700377status_t Camera2Device::deleteReprocessStream(int id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700378 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700379 ALOGV("%s: E", __FUNCTION__);
380 bool found = false;
381 for (ReprocessStreamList::iterator streamI = mReprocessStreams.begin();
382 streamI != mReprocessStreams.end(); streamI++) {
383 if ((*streamI)->getId() == id) {
384 status_t res = (*streamI)->release();
385 if (res != OK) {
386 ALOGE("%s: Unable to release reprocess stream %d from "
387 "HAL device: %s (%d)", __FUNCTION__, id,
388 strerror(-res), res);
389 return res;
390 }
391 mReprocessStreams.erase(streamI);
392 found = true;
393 break;
394 }
395 }
396 if (!found) {
397 ALOGE("%s: Camera %d: Unable to find stream %d to delete",
398 __FUNCTION__, mId, id);
399 return BAD_VALUE;
400 }
401 return OK;
402}
403
404
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700405status_t Camera2Device::createDefaultRequest(int templateId,
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700406 CameraMetadata *request) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700407 ATRACE_CALL();
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700408 status_t err;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700409 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700410 camera_metadata_t *rawRequest;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800411 err = mHal2Device->ops->construct_default_request(
412 mHal2Device, templateId, &rawRequest);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700413 request->acquire(rawRequest);
414 return err;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700415}
416
417status_t Camera2Device::waitUntilDrained() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700418 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700419 static const uint32_t kSleepTime = 50000; // 50 ms
420 static const uint32_t kMaxSleepTime = 10000000; // 10 s
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700421 ALOGV("%s: Camera %d: Starting wait", __FUNCTION__, mId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700422 if (mRequestQueue.getBufferCount() ==
423 CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS) return INVALID_OPERATION;
424
425 // TODO: Set up notifications from HAL, instead of sleeping here
426 uint32_t totalTime = 0;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800427 while (mHal2Device->ops->get_in_progress_count(mHal2Device) > 0) {
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700428 usleep(kSleepTime);
429 totalTime += kSleepTime;
430 if (totalTime > kMaxSleepTime) {
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700431 ALOGE("%s: Waited %d us, %d requests still in flight", __FUNCTION__,
Alex Rayf0eeb532013-03-17 03:23:18 -0700432 totalTime, mHal2Device->ops->get_in_progress_count(mHal2Device));
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700433 return TIMED_OUT;
434 }
435 }
Eino-Ville Talvala7adb52f2012-09-20 14:44:20 -0700436 ALOGV("%s: Camera %d: HAL is idle", __FUNCTION__, mId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700437 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700438}
439
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700440status_t Camera2Device::setNotifyCallback(NotificationListener *listener) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700441 ATRACE_CALL();
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700442 status_t res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800443 res = mHal2Device->ops->set_notify_callback(mHal2Device, notificationCallback,
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700444 reinterpret_cast<void*>(listener) );
445 if (res != OK) {
446 ALOGE("%s: Unable to set notification callback!", __FUNCTION__);
447 }
448 return res;
449}
450
Eino-Ville Talvala46910bd2013-07-18 19:15:17 -0700451bool Camera2Device::willNotify3A() {
452 return true;
453}
454
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700455void Camera2Device::notificationCallback(int32_t msg_type,
456 int32_t ext1,
457 int32_t ext2,
458 int32_t ext3,
459 void *user) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700460 ATRACE_CALL();
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700461 NotificationListener *listener = reinterpret_cast<NotificationListener*>(user);
462 ALOGV("%s: Notification %d, arguments %d, %d, %d", __FUNCTION__, msg_type,
463 ext1, ext2, ext3);
464 if (listener != NULL) {
465 switch (msg_type) {
466 case CAMERA2_MSG_ERROR:
Jianing Weicb0652e2014-03-12 18:29:36 -0700467 // TODO: This needs to be fixed. ext2 and ext3 need to be considered.
468 listener->notifyError(
469 ((ext1 == CAMERA2_MSG_ERROR_DEVICE)
470 || (ext1 == CAMERA2_MSG_ERROR_HARDWARE)) ?
471 ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE :
472 ICameraDeviceCallbacks::ERROR_CAMERA_SERVICE,
473 CaptureResultExtras());
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700474 break;
475 case CAMERA2_MSG_SHUTTER: {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700476 // TODO: Only needed for camera2 API, which is unsupported
477 // by HAL2 directly.
478 // nsecs_t timestamp = (nsecs_t)ext2 | ((nsecs_t)(ext3) << 32 );
479 // listener->notifyShutter(requestId, timestamp);
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700480 break;
481 }
482 case CAMERA2_MSG_AUTOFOCUS:
483 listener->notifyAutoFocus(ext1, ext2);
484 break;
485 case CAMERA2_MSG_AUTOEXPOSURE:
486 listener->notifyAutoExposure(ext1, ext2);
487 break;
488 case CAMERA2_MSG_AUTOWB:
489 listener->notifyAutoWhitebalance(ext1, ext2);
490 break;
491 default:
492 ALOGE("%s: Unknown notification %d (arguments %d, %d, %d)!",
493 __FUNCTION__, msg_type, ext1, ext2, ext3);
494 }
495 }
496}
497
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -0700498status_t Camera2Device::waitForNextFrame(nsecs_t timeout) {
499 return mFrameQueue.waitForBuffer(timeout);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700500}
501
Jianing Weicb0652e2014-03-12 18:29:36 -0700502status_t Camera2Device::getNextResult(CaptureResult *result) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700503 ATRACE_CALL();
Jianing Weicb0652e2014-03-12 18:29:36 -0700504 ALOGV("%s: get CaptureResult", __FUNCTION__);
505 if (result == NULL) {
506 ALOGE("%s: result pointer is NULL", __FUNCTION__);
507 return BAD_VALUE;
508 }
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700509 status_t res;
510 camera_metadata_t *rawFrame;
511 res = mFrameQueue.dequeue(&rawFrame);
Jianing Weicb0652e2014-03-12 18:29:36 -0700512 if (rawFrame == NULL) {
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700513 return NOT_ENOUGH_DATA;
514 } else if (res == OK) {
Jianing Weicb0652e2014-03-12 18:29:36 -0700515 result->mMetadata.acquire(rawFrame);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700516 }
Jianing Weicb0652e2014-03-12 18:29:36 -0700517
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700518 return res;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700519}
520
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700521status_t Camera2Device::triggerAutofocus(uint32_t id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700522 ATRACE_CALL();
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700523 status_t res;
524 ALOGV("%s: Triggering autofocus, id %d", __FUNCTION__, id);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800525 res = mHal2Device->ops->trigger_action(mHal2Device,
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700526 CAMERA2_TRIGGER_AUTOFOCUS, id, 0);
527 if (res != OK) {
528 ALOGE("%s: Error triggering autofocus (id %d)",
529 __FUNCTION__, id);
530 }
531 return res;
532}
533
534status_t Camera2Device::triggerCancelAutofocus(uint32_t id) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700535 ATRACE_CALL();
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700536 status_t res;
537 ALOGV("%s: Canceling autofocus, id %d", __FUNCTION__, id);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800538 res = mHal2Device->ops->trigger_action(mHal2Device,
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700539 CAMERA2_TRIGGER_CANCEL_AUTOFOCUS, id, 0);
540 if (res != OK) {
541 ALOGE("%s: Error canceling autofocus (id %d)",
542 __FUNCTION__, id);
543 }
544 return res;
545}
546
547status_t Camera2Device::triggerPrecaptureMetering(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 precapture metering, 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_PRECAPTURE_METERING, id, 0);
553 if (res != OK) {
554 ALOGE("%s: Error triggering precapture metering (id %d)",
555 __FUNCTION__, id);
556 }
557 return res;
558}
559
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700560status_t Camera2Device::pushReprocessBuffer(int reprocessStreamId,
561 buffer_handle_t *buffer, wp<BufferReleasedListener> listener) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700562 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -0700563 ALOGV("%s: E", __FUNCTION__);
564 bool found = false;
565 status_t res = OK;
566 for (ReprocessStreamList::iterator streamI = mReprocessStreams.begin();
567 streamI != mReprocessStreams.end(); streamI++) {
568 if ((*streamI)->getId() == reprocessStreamId) {
569 res = (*streamI)->pushIntoStream(buffer, listener);
570 if (res != OK) {
571 ALOGE("%s: Unable to push buffer to reprocess stream %d: %s (%d)",
572 __FUNCTION__, reprocessStreamId, strerror(-res), res);
573 return res;
574 }
575 found = true;
576 break;
577 }
578 }
579 if (!found) {
580 ALOGE("%s: Camera %d: Unable to find reprocess stream %d",
581 __FUNCTION__, mId, reprocessStreamId);
582 res = BAD_VALUE;
583 }
584 return res;
585}
586
Jianing Weicb0652e2014-03-12 18:29:36 -0700587status_t Camera2Device::flush(int64_t* /*lastFrameNumber*/) {
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -0700588 ATRACE_CALL();
589
590 mRequestQueue.clear();
591 return waitUntilDrained();
592}
593
Zhijun He204e3292014-07-14 17:09:23 -0700594uint32_t Camera2Device::getDeviceVersion() {
595 ATRACE_CALL();
596 return mDeviceVersion;
597}
598
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700599/**
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700600 * Camera2Device::MetadataQueue
601 */
602
603Camera2Device::MetadataQueue::MetadataQueue():
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800604 mHal2Device(NULL),
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700605 mFrameCount(0),
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700606 mLatestRequestId(0),
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700607 mCount(0),
608 mStreamSlotCount(0),
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -0700609 mSignalConsumer(true)
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700610{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700611 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700612 camera2_request_queue_src_ops::dequeue_request = consumer_dequeue;
613 camera2_request_queue_src_ops::request_count = consumer_buffer_count;
614 camera2_request_queue_src_ops::free_request = consumer_free;
615
616 camera2_frame_queue_dst_ops::dequeue_frame = producer_dequeue;
617 camera2_frame_queue_dst_ops::cancel_frame = producer_cancel;
618 camera2_frame_queue_dst_ops::enqueue_frame = producer_enqueue;
619}
620
621Camera2Device::MetadataQueue::~MetadataQueue() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700622 ATRACE_CALL();
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -0700623 clear();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700624}
625
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700626// Connect to camera2 HAL as consumer (input requests/reprocessing)
627status_t Camera2Device::MetadataQueue::setConsumerDevice(camera2_device_t *d) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700628 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700629 status_t res;
630 res = d->ops->set_request_queue_src_ops(d,
631 this);
632 if (res != OK) return res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800633 mHal2Device = d;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700634 return OK;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700635}
636
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700637status_t Camera2Device::MetadataQueue::setProducerDevice(camera2_device_t *d) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700638 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700639 status_t res;
640 res = d->ops->set_frame_queue_dst_ops(d,
641 this);
642 return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700643}
644
645// Real interfaces
646status_t Camera2Device::MetadataQueue::enqueue(camera_metadata_t *buf) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700647 ATRACE_CALL();
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700648 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700649 Mutex::Autolock l(mMutex);
650
651 mCount++;
652 mEntries.push_back(buf);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700653
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700654 return signalConsumerLocked();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700655}
656
657int Camera2Device::MetadataQueue::getBufferCount() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700658 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700659 Mutex::Autolock l(mMutex);
660 if (mStreamSlotCount > 0) {
661 return CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS;
662 }
663 return mCount;
664}
665
666status_t Camera2Device::MetadataQueue::dequeue(camera_metadata_t **buf,
667 bool incrementCount)
668{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700669 ATRACE_CALL();
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700670 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700671 status_t res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700672 Mutex::Autolock l(mMutex);
673
674 if (mCount == 0) {
675 if (mStreamSlotCount == 0) {
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700676 ALOGVV("%s: Empty", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700677 *buf = NULL;
678 mSignalConsumer = true;
679 return OK;
680 }
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700681 ALOGVV("%s: Streaming %d frames to queue", __FUNCTION__,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700682 mStreamSlotCount);
683
684 for (List<camera_metadata_t*>::iterator slotEntry = mStreamSlot.begin();
685 slotEntry != mStreamSlot.end();
686 slotEntry++ ) {
687 size_t entries = get_camera_metadata_entry_count(*slotEntry);
688 size_t dataBytes = get_camera_metadata_data_count(*slotEntry);
689
690 camera_metadata_t *copy =
691 allocate_camera_metadata(entries, dataBytes);
692 append_camera_metadata(copy, *slotEntry);
693 mEntries.push_back(copy);
694 }
695 mCount = mStreamSlotCount;
696 }
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700697 ALOGVV("MetadataQueue: deque (%d buffers)", mCount);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700698 camera_metadata_t *b = *(mEntries.begin());
699 mEntries.erase(mEntries.begin());
700
701 if (incrementCount) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700702 ATRACE_INT("cam2_request", mFrameCount);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700703 camera_metadata_entry_t frameCount;
704 res = find_camera_metadata_entry(b,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700705 ANDROID_REQUEST_FRAME_COUNT,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700706 &frameCount);
707 if (res != OK) {
708 ALOGE("%s: Unable to add frame count: %s (%d)",
709 __FUNCTION__, strerror(-res), res);
710 } else {
711 *frameCount.data.i32 = mFrameCount;
712 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700713 mFrameCount++;
714 }
715
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700716 // Check for request ID, and if present, signal waiters.
717 camera_metadata_entry_t requestId;
718 res = find_camera_metadata_entry(b,
719 ANDROID_REQUEST_ID,
720 &requestId);
721 if (res == OK) {
722 mLatestRequestId = requestId.data.i32[0];
723 mNewRequestId.signal();
724 }
725
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700726 *buf = b;
727 mCount--;
728
729 return OK;
730}
731
732status_t Camera2Device::MetadataQueue::waitForBuffer(nsecs_t timeout)
733{
734 Mutex::Autolock l(mMutex);
735 status_t res;
736 while (mCount == 0) {
737 res = notEmpty.waitRelative(mMutex,timeout);
738 if (res != OK) return res;
739 }
740 return OK;
741}
742
Eino-Ville Talvala4c9eb712012-10-02 13:30:28 -0700743status_t Camera2Device::MetadataQueue::waitForDequeue(int32_t id,
744 nsecs_t timeout) {
745 Mutex::Autolock l(mMutex);
746 status_t res;
747 while (mLatestRequestId != id) {
748 nsecs_t startTime = systemTime();
749
750 res = mNewRequestId.waitRelative(mMutex, timeout);
751 if (res != OK) return res;
752
753 timeout -= (systemTime() - startTime);
754 }
755
756 return OK;
757}
758
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700759status_t Camera2Device::MetadataQueue::setStreamSlot(camera_metadata_t *buf)
760{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700761 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700762 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700763 Mutex::Autolock l(mMutex);
764 if (buf == NULL) {
765 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
766 mStreamSlotCount = 0;
767 return OK;
768 }
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700769 camera_metadata_t *buf2 = clone_camera_metadata(buf);
770 if (!buf2) {
771 ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__);
772 return NO_MEMORY;
773 }
774
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700775 if (mStreamSlotCount > 1) {
776 List<camera_metadata_t*>::iterator deleter = ++mStreamSlot.begin();
777 freeBuffers(++mStreamSlot.begin(), mStreamSlot.end());
778 mStreamSlotCount = 1;
779 }
780 if (mStreamSlotCount == 1) {
781 free_camera_metadata( *(mStreamSlot.begin()) );
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700782 *(mStreamSlot.begin()) = buf2;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700783 } else {
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700784 mStreamSlot.push_front(buf2);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700785 mStreamSlotCount = 1;
786 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700787 return signalConsumerLocked();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700788}
789
790status_t Camera2Device::MetadataQueue::setStreamSlot(
791 const List<camera_metadata_t*> &bufs)
792{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700793 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700794 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700795 Mutex::Autolock l(mMutex);
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700796
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700797 if (mStreamSlotCount > 0) {
798 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
799 }
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700800 mStreamSlotCount = 0;
801 for (List<camera_metadata_t*>::const_iterator r = bufs.begin();
802 r != bufs.end(); r++) {
803 camera_metadata_t *r2 = clone_camera_metadata(*r);
804 if (!r2) {
805 ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__);
806 return NO_MEMORY;
807 }
808 mStreamSlot.push_back(r2);
809 mStreamSlotCount++;
810 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700811 return signalConsumerLocked();
812}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700813
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -0700814status_t Camera2Device::MetadataQueue::clear()
815{
816 ATRACE_CALL();
817 ALOGV("%s: E", __FUNCTION__);
818
819 Mutex::Autolock l(mMutex);
820
821 // Clear streaming slot
822 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
823 mStreamSlotCount = 0;
824
825 // Clear request queue
826 freeBuffers(mEntries.begin(), mEntries.end());
827 mCount = 0;
828 return OK;
829}
830
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700831status_t Camera2Device::MetadataQueue::dump(int fd,
Igor Murashkinebe3f692012-10-12 16:56:11 -0700832 const Vector<String16>& /*args*/) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700833 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700834 String8 result;
835 status_t notLocked;
836 notLocked = mMutex.tryLock();
837 if (notLocked) {
838 result.append(" (Unable to lock queue mutex)\n");
839 }
840 result.appendFormat(" Current frame number: %d\n", mFrameCount);
841 if (mStreamSlotCount == 0) {
842 result.append(" Stream slot: Empty\n");
843 write(fd, result.string(), result.size());
844 } else {
Kévin PETIT377b2ec2014-02-03 12:35:36 +0000845 result.appendFormat(" Stream slot: %zu entries\n",
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700846 mStreamSlot.size());
847 int i = 0;
848 for (List<camera_metadata_t*>::iterator r = mStreamSlot.begin();
849 r != mStreamSlot.end(); r++) {
850 result = String8::format(" Stream slot buffer %d:\n", i);
851 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700852 dump_indented_camera_metadata(*r, fd, 2, 10);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700853 i++;
854 }
855 }
856 if (mEntries.size() == 0) {
857 result = " Main queue is empty\n";
858 write(fd, result.string(), result.size());
859 } else {
Kévin PETIT377b2ec2014-02-03 12:35:36 +0000860 result = String8::format(" Main queue has %zu entries:\n",
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700861 mEntries.size());
862 int i = 0;
863 for (List<camera_metadata_t*>::iterator r = mEntries.begin();
864 r != mEntries.end(); r++) {
865 result = String8::format(" Queue entry %d:\n", i);
866 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700867 dump_indented_camera_metadata(*r, fd, 2, 10);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700868 i++;
869 }
870 }
871
872 if (notLocked == 0) {
873 mMutex.unlock();
874 }
875
876 return OK;
877}
878
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700879status_t Camera2Device::MetadataQueue::signalConsumerLocked() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700880 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700881 status_t res = OK;
882 notEmpty.signal();
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800883 if (mSignalConsumer && mHal2Device != NULL) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700884 mSignalConsumer = false;
885
886 mMutex.unlock();
887 ALOGV("%s: Signaling consumer", __FUNCTION__);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800888 res = mHal2Device->ops->notify_request_queue_not_empty(mHal2Device);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700889 mMutex.lock();
890 }
891 return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700892}
893
894status_t Camera2Device::MetadataQueue::freeBuffers(
895 List<camera_metadata_t*>::iterator start,
896 List<camera_metadata_t*>::iterator end)
897{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700898 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700899 while (start != end) {
900 free_camera_metadata(*start);
901 start = mStreamSlot.erase(start);
902 }
903 return OK;
904}
905
906Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
907 const camera2_request_queue_src_ops_t *q)
908{
909 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
910 return const_cast<MetadataQueue*>(cmq);
911}
912
913Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
914 const camera2_frame_queue_dst_ops_t *q)
915{
916 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
917 return const_cast<MetadataQueue*>(cmq);
918}
919
920int Camera2Device::MetadataQueue::consumer_buffer_count(
921 const camera2_request_queue_src_ops_t *q)
922{
923 MetadataQueue *queue = getInstance(q);
924 return queue->getBufferCount();
925}
926
927int Camera2Device::MetadataQueue::consumer_dequeue(
928 const camera2_request_queue_src_ops_t *q,
929 camera_metadata_t **buffer)
930{
931 MetadataQueue *queue = getInstance(q);
932 return queue->dequeue(buffer, true);
933}
934
935int Camera2Device::MetadataQueue::consumer_free(
936 const camera2_request_queue_src_ops_t *q,
937 camera_metadata_t *old_buffer)
938{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700939 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700940 MetadataQueue *queue = getInstance(q);
Igor Murashkinebe3f692012-10-12 16:56:11 -0700941 (void)queue;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700942 free_camera_metadata(old_buffer);
943 return OK;
944}
945
946int Camera2Device::MetadataQueue::producer_dequeue(
Igor Murashkinebe3f692012-10-12 16:56:11 -0700947 const camera2_frame_queue_dst_ops_t * /*q*/,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700948 size_t entries, size_t bytes,
949 camera_metadata_t **buffer)
950{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700951 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700952 camera_metadata_t *new_buffer =
953 allocate_camera_metadata(entries, bytes);
954 if (new_buffer == NULL) return NO_MEMORY;
955 *buffer = new_buffer;
956 return OK;
957}
958
959int Camera2Device::MetadataQueue::producer_cancel(
Igor Murashkinebe3f692012-10-12 16:56:11 -0700960 const camera2_frame_queue_dst_ops_t * /*q*/,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700961 camera_metadata_t *old_buffer)
962{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -0700963 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700964 free_camera_metadata(old_buffer);
965 return OK;
966}
967
968int Camera2Device::MetadataQueue::producer_enqueue(
969 const camera2_frame_queue_dst_ops_t *q,
970 camera_metadata_t *filled_buffer)
971{
972 MetadataQueue *queue = getInstance(q);
973 return queue->enqueue(filled_buffer);
974}
975
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700976/**
977 * Camera2Device::StreamAdapter
978 */
979
980#ifndef container_of
981#define container_of(ptr, type, member) \
982 (type *)((char*)(ptr) - offsetof(type, member))
983#endif
984
985Camera2Device::StreamAdapter::StreamAdapter(camera2_device_t *d):
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700986 mState(RELEASED),
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800987 mHal2Device(d),
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700988 mId(-1),
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700989 mWidth(0), mHeight(0), mFormat(0), mSize(0), mUsage(0),
990 mMaxProducerBuffers(0), mMaxConsumerBuffers(0),
991 mTotalBuffers(0),
992 mFormatRequested(0),
993 mActiveBuffers(0),
994 mFrameCount(0),
995 mLastTimestamp(0)
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700996{
997 camera2_stream_ops::dequeue_buffer = dequeue_buffer;
998 camera2_stream_ops::enqueue_buffer = enqueue_buffer;
999 camera2_stream_ops::cancel_buffer = cancel_buffer;
1000 camera2_stream_ops::set_crop = set_crop;
1001}
1002
1003Camera2Device::StreamAdapter::~StreamAdapter() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001004 ATRACE_CALL();
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001005 if (mState != RELEASED) {
1006 release();
1007 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001008}
1009
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001010status_t Camera2Device::StreamAdapter::connectToDevice(
1011 sp<ANativeWindow> consumer,
1012 uint32_t width, uint32_t height, int format, size_t size) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001013 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001014 status_t res;
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -07001015 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001016
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001017 if (mState != RELEASED) return INVALID_OPERATION;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001018 if (consumer == NULL) {
1019 ALOGE("%s: Null consumer passed to stream adapter", __FUNCTION__);
1020 return BAD_VALUE;
1021 }
1022
Colin Crosse5729fa2014-03-21 15:04:25 -07001023 ALOGV("%s: New stream parameters %d x %d, format 0x%x, size %zu",
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001024 __FUNCTION__, width, height, format, size);
1025
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001026 mConsumerInterface = consumer;
1027 mWidth = width;
1028 mHeight = height;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001029 mSize = (format == HAL_PIXEL_FORMAT_BLOB) ? size : 0;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001030 mFormatRequested = format;
1031
1032 // Allocate device-side stream interface
1033
1034 uint32_t id;
1035 uint32_t formatActual;
1036 uint32_t usage;
1037 uint32_t maxBuffers = 2;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001038 res = mHal2Device->ops->allocate_stream(mHal2Device,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001039 mWidth, mHeight, mFormatRequested, getStreamOps(),
1040 &id, &formatActual, &usage, &maxBuffers);
1041 if (res != OK) {
1042 ALOGE("%s: Device stream allocation failed: %s (%d)",
1043 __FUNCTION__, strerror(-res), res);
1044 return res;
1045 }
1046
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001047 ALOGV("%s: Allocated stream id %d, actual format 0x%x, "
1048 "usage 0x%x, producer wants %d buffers", __FUNCTION__,
1049 id, formatActual, usage, maxBuffers);
1050
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001051 mId = id;
1052 mFormat = formatActual;
1053 mUsage = usage;
1054 mMaxProducerBuffers = maxBuffers;
1055
1056 mState = ALLOCATED;
1057
1058 // Configure consumer-side ANativeWindow interface
1059 res = native_window_api_connect(mConsumerInterface.get(),
1060 NATIVE_WINDOW_API_CAMERA);
1061 if (res != OK) {
1062 ALOGE("%s: Unable to connect to native window for stream %d",
1063 __FUNCTION__, mId);
1064
1065 return res;
1066 }
1067
1068 mState = CONNECTED;
1069
1070 res = native_window_set_usage(mConsumerInterface.get(), mUsage);
1071 if (res != OK) {
1072 ALOGE("%s: Unable to configure usage %08x for stream %d",
1073 __FUNCTION__, mUsage, mId);
1074 return res;
1075 }
1076
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001077 res = native_window_set_scaling_mode(mConsumerInterface.get(),
1078 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
1079 if (res != OK) {
1080 ALOGE("%s: Unable to configure stream scaling: %s (%d)",
1081 __FUNCTION__, strerror(-res), res);
1082 return res;
1083 }
1084
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001085 res = setTransform(0);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001086 if (res != OK) {
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001087 return res;
1088 }
1089
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001090 if (mFormat == HAL_PIXEL_FORMAT_BLOB) {
Eino-Ville Talvala7d70c5e2014-07-24 18:10:23 -07001091 res = native_window_set_buffers_dimensions(mConsumerInterface.get(),
1092 mSize, 1);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001093 if (res != OK) {
Eino-Ville Talvala7d70c5e2014-07-24 18:10:23 -07001094 ALOGE("%s: Unable to configure compressed stream buffer dimensions"
Colin Crosse5729fa2014-03-21 15:04:25 -07001095 " %d x %d, size %zu for stream %d",
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001096 __FUNCTION__, mWidth, mHeight, mSize, mId);
1097 return res;
1098 }
1099 } else {
Eino-Ville Talvala7d70c5e2014-07-24 18:10:23 -07001100 res = native_window_set_buffers_dimensions(mConsumerInterface.get(),
1101 mWidth, mHeight);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001102 if (res != OK) {
Eino-Ville Talvala7d70c5e2014-07-24 18:10:23 -07001103 ALOGE("%s: Unable to configure stream buffer dimensions"
1104 " %d x %d for stream %d",
1105 __FUNCTION__, mWidth, mHeight, mId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001106 return res;
1107 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001108 }
1109
Eino-Ville Talvala7d70c5e2014-07-24 18:10:23 -07001110 res = native_window_set_buffers_format(mConsumerInterface.get(), mFormat);
1111 if (res != OK) {
1112 ALOGE("%s: Unable to configure stream buffer format"
1113 " %#x for stream %d",
1114 __FUNCTION__, mFormat, mId);
1115 return res;
1116 }
1117
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001118 int maxConsumerBuffers;
1119 res = mConsumerInterface->query(mConsumerInterface.get(),
1120 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &maxConsumerBuffers);
1121 if (res != OK) {
1122 ALOGE("%s: Unable to query consumer undequeued"
1123 " buffer count for stream %d", __FUNCTION__, mId);
1124 return res;
1125 }
1126 mMaxConsumerBuffers = maxConsumerBuffers;
1127
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001128 ALOGV("%s: Consumer wants %d buffers", __FUNCTION__,
1129 mMaxConsumerBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001130
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001131 mTotalBuffers = mMaxConsumerBuffers + mMaxProducerBuffers;
1132 mActiveBuffers = 0;
1133 mFrameCount = 0;
1134 mLastTimestamp = 0;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001135
1136 res = native_window_set_buffer_count(mConsumerInterface.get(),
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001137 mTotalBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001138 if (res != OK) {
1139 ALOGE("%s: Unable to set buffer count for stream %d",
1140 __FUNCTION__, mId);
1141 return res;
1142 }
1143
1144 // Register allocated buffers with HAL device
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001145 buffer_handle_t *buffers = new buffer_handle_t[mTotalBuffers];
1146 ANativeWindowBuffer **anwBuffers = new ANativeWindowBuffer*[mTotalBuffers];
1147 uint32_t bufferIdx = 0;
1148 for (; bufferIdx < mTotalBuffers; bufferIdx++) {
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001149 res = native_window_dequeue_buffer_and_wait(mConsumerInterface.get(),
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001150 &anwBuffers[bufferIdx]);
1151 if (res != OK) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001152 ALOGE("%s: Unable to dequeue buffer %d for initial registration for "
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001153 "stream %d", __FUNCTION__, bufferIdx, mId);
1154 goto cleanUpBuffers;
1155 }
1156
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001157 buffers[bufferIdx] = anwBuffers[bufferIdx]->handle;
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001158 ALOGV("%s: Buffer %p allocated", __FUNCTION__, (void*)buffers[bufferIdx]);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001159 }
1160
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001161 ALOGV("%s: Registering %d buffers with camera HAL", __FUNCTION__, mTotalBuffers);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001162 res = mHal2Device->ops->register_stream_buffers(mHal2Device,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001163 mId,
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001164 mTotalBuffers,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001165 buffers);
1166 if (res != OK) {
1167 ALOGE("%s: Unable to register buffers with HAL device for stream %d",
1168 __FUNCTION__, mId);
1169 } else {
1170 mState = ACTIVE;
1171 }
1172
1173cleanUpBuffers:
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001174 ALOGV("%s: Cleaning up %d buffers", __FUNCTION__, bufferIdx);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001175 for (uint32_t i = 0; i < bufferIdx; i++) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001176 res = mConsumerInterface->cancelBuffer(mConsumerInterface.get(),
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001177 anwBuffers[i], -1);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001178 if (res != OK) {
1179 ALOGE("%s: Unable to cancel buffer %d after registration",
1180 __FUNCTION__, i);
1181 }
1182 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001183 delete[] anwBuffers;
1184 delete[] buffers;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001185
1186 return res;
1187}
1188
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001189status_t Camera2Device::StreamAdapter::release() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001190 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001191 status_t res;
Eino-Ville Talvala02f84572013-04-23 15:16:57 -07001192 ALOGV("%s: Releasing stream %d (%d x %d, format %d)", __FUNCTION__, mId,
1193 mWidth, mHeight, mFormat);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001194 if (mState >= ALLOCATED) {
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001195 res = mHal2Device->ops->release_stream(mHal2Device, mId);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001196 if (res != OK) {
1197 ALOGE("%s: Unable to release stream %d",
1198 __FUNCTION__, mId);
1199 return res;
1200 }
1201 }
1202 if (mState >= CONNECTED) {
1203 res = native_window_api_disconnect(mConsumerInterface.get(),
1204 NATIVE_WINDOW_API_CAMERA);
Igor Murashkina1e5dcc2012-10-02 15:21:31 -07001205
1206 /* this is not an error. if client calling process dies,
1207 the window will also die and all calls to it will return
1208 DEAD_OBJECT, thus it's already "disconnected" */
1209 if (res == DEAD_OBJECT) {
1210 ALOGW("%s: While disconnecting stream %d from native window, the"
1211 " native window died from under us", __FUNCTION__, mId);
1212 }
1213 else if (res != OK) {
1214 ALOGE("%s: Unable to disconnect stream %d from native window (error %d %s)",
1215 __FUNCTION__, mId, res, strerror(-res));
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001216 return res;
1217 }
1218 }
1219 mId = -1;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001220 mState = RELEASED;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001221 return OK;
1222}
1223
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001224status_t Camera2Device::StreamAdapter::setTransform(int transform) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001225 ATRACE_CALL();
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001226 status_t res;
1227 if (mState < CONNECTED) {
1228 ALOGE("%s: Cannot set transform on unconnected stream", __FUNCTION__);
1229 return INVALID_OPERATION;
1230 }
1231 res = native_window_set_buffers_transform(mConsumerInterface.get(),
1232 transform);
1233 if (res != OK) {
1234 ALOGE("%s: Unable to configure stream transform to %x: %s (%d)",
1235 __FUNCTION__, transform, strerror(-res), res);
1236 }
1237 return res;
1238}
1239
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001240status_t Camera2Device::StreamAdapter::dump(int fd,
Igor Murashkinebe3f692012-10-12 16:56:11 -07001241 const Vector<String16>& /*args*/) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001242 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001243 String8 result = String8::format(" Stream %d: %d x %d, format 0x%x\n",
1244 mId, mWidth, mHeight, mFormat);
Kévin PETIT377b2ec2014-02-03 12:35:36 +00001245 result.appendFormat(" size %zu, usage 0x%x, requested format 0x%x\n",
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001246 mSize, mUsage, mFormatRequested);
1247 result.appendFormat(" total buffers: %d, dequeued buffers: %d\n",
1248 mTotalBuffers, mActiveBuffers);
Kévin PETIT377b2ec2014-02-03 12:35:36 +00001249 result.appendFormat(" frame count: %d, last timestamp %" PRId64 "\n",
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001250 mFrameCount, mLastTimestamp);
1251 write(fd, result.string(), result.size());
1252 return OK;
1253}
1254
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001255const camera2_stream_ops *Camera2Device::StreamAdapter::getStreamOps() {
1256 return static_cast<camera2_stream_ops *>(this);
1257}
1258
1259ANativeWindow* Camera2Device::StreamAdapter::toANW(
1260 const camera2_stream_ops_t *w) {
1261 return static_cast<const StreamAdapter*>(w)->mConsumerInterface.get();
1262}
1263
1264int Camera2Device::StreamAdapter::dequeue_buffer(const camera2_stream_ops_t *w,
1265 buffer_handle_t** buffer) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001266 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001267 int res;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001268 StreamAdapter* stream =
1269 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
1270 if (stream->mState != ACTIVE) {
1271 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001272 return INVALID_OPERATION;
1273 }
1274
1275 ANativeWindow *a = toANW(w);
1276 ANativeWindowBuffer* anb;
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001277 res = native_window_dequeue_buffer_and_wait(a, &anb);
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001278 if (res != OK) {
1279 ALOGE("Stream %d dequeue: Error from native_window: %s (%d)", stream->mId,
1280 strerror(-res), res);
1281 return res;
1282 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001283
1284 *buffer = &(anb->handle);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001285 stream->mActiveBuffers++;
1286
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001287 ALOGVV("Stream %d dequeue: Buffer %p dequeued", stream->mId, (void*)(**buffer));
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001288 return res;
1289}
1290
1291int Camera2Device::StreamAdapter::enqueue_buffer(const camera2_stream_ops_t* w,
1292 int64_t timestamp,
1293 buffer_handle_t* buffer) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001294 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001295 StreamAdapter *stream =
1296 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001297 stream->mFrameCount++;
1298 ALOGVV("Stream %d enqueue: Frame %d (%p) captured at %lld ns",
James Donga289bf62012-09-05 16:46:36 -07001299 stream->mId, stream->mFrameCount, (void*)(*buffer), timestamp);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001300 int state = stream->mState;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001301 if (state != ACTIVE) {
1302 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1303 return INVALID_OPERATION;
1304 }
1305 ANativeWindow *a = toANW(w);
1306 status_t err;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001307
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001308 err = native_window_set_buffers_timestamp(a, timestamp);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001309 if (err != OK) {
1310 ALOGE("%s: Error setting timestamp on native window: %s (%d)",
1311 __FUNCTION__, strerror(-err), err);
1312 return err;
1313 }
1314 err = a->queueBuffer(a,
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001315 container_of(buffer, ANativeWindowBuffer, handle), -1);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001316 if (err != OK) {
1317 ALOGE("%s: Error queueing buffer to native window: %s (%d)",
1318 __FUNCTION__, strerror(-err), err);
James Dong31d377b2012-08-09 17:43:46 -07001319 return err;
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001320 }
James Dong31d377b2012-08-09 17:43:46 -07001321
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001322 stream->mActiveBuffers--;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001323 stream->mLastTimestamp = timestamp;
James Dong31d377b2012-08-09 17:43:46 -07001324 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001325}
1326
1327int Camera2Device::StreamAdapter::cancel_buffer(const camera2_stream_ops_t* w,
1328 buffer_handle_t* buffer) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001329 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001330 StreamAdapter *stream =
1331 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001332 ALOGVV("Stream %d cancel: Buffer %p",
1333 stream->mId, (void*)(*buffer));
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001334 if (stream->mState != ACTIVE) {
1335 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001336 return INVALID_OPERATION;
1337 }
James Dong31d377b2012-08-09 17:43:46 -07001338
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001339 ANativeWindow *a = toANW(w);
James Dong31d377b2012-08-09 17:43:46 -07001340 int err = a->cancelBuffer(a,
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001341 container_of(buffer, ANativeWindowBuffer, handle), -1);
James Dong31d377b2012-08-09 17:43:46 -07001342 if (err != OK) {
1343 ALOGE("%s: Error canceling buffer to native window: %s (%d)",
1344 __FUNCTION__, strerror(-err), err);
1345 return err;
1346 }
1347
1348 stream->mActiveBuffers--;
1349 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001350}
1351
1352int Camera2Device::StreamAdapter::set_crop(const camera2_stream_ops_t* w,
1353 int left, int top, int right, int bottom) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001354 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001355 int state = static_cast<const StreamAdapter*>(w)->mState;
1356 if (state != ACTIVE) {
1357 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1358 return INVALID_OPERATION;
1359 }
1360 ANativeWindow *a = toANW(w);
1361 android_native_rect_t crop = { left, top, right, bottom };
1362 return native_window_set_crop(a, &crop);
1363}
1364
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001365/**
1366 * Camera2Device::ReprocessStreamAdapter
1367 */
1368
1369#ifndef container_of
1370#define container_of(ptr, type, member) \
1371 (type *)((char*)(ptr) - offsetof(type, member))
1372#endif
1373
1374Camera2Device::ReprocessStreamAdapter::ReprocessStreamAdapter(camera2_device_t *d):
1375 mState(RELEASED),
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001376 mHal2Device(d),
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001377 mId(-1),
1378 mWidth(0), mHeight(0), mFormat(0),
1379 mActiveBuffers(0),
1380 mFrameCount(0)
1381{
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001382 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001383 camera2_stream_in_ops::acquire_buffer = acquire_buffer;
1384 camera2_stream_in_ops::release_buffer = release_buffer;
1385}
1386
1387Camera2Device::ReprocessStreamAdapter::~ReprocessStreamAdapter() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001388 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001389 if (mState != RELEASED) {
1390 release();
1391 }
1392}
1393
1394status_t Camera2Device::ReprocessStreamAdapter::connectToDevice(
1395 const sp<StreamAdapter> &outputStream) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001396 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001397 status_t res;
1398 ALOGV("%s: E", __FUNCTION__);
1399
1400 if (mState != RELEASED) return INVALID_OPERATION;
1401 if (outputStream == NULL) {
1402 ALOGE("%s: Null base stream passed to reprocess stream adapter",
1403 __FUNCTION__);
1404 return BAD_VALUE;
1405 }
1406
1407 mBaseStream = outputStream;
1408 mWidth = outputStream->getWidth();
1409 mHeight = outputStream->getHeight();
1410 mFormat = outputStream->getFormat();
1411
1412 ALOGV("%s: New reprocess stream parameters %d x %d, format 0x%x",
1413 __FUNCTION__, mWidth, mHeight, mFormat);
1414
1415 // Allocate device-side stream interface
1416
1417 uint32_t id;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001418 res = mHal2Device->ops->allocate_reprocess_stream_from_stream(mHal2Device,
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001419 outputStream->getId(), getStreamOps(),
1420 &id);
1421 if (res != OK) {
1422 ALOGE("%s: Device reprocess stream allocation failed: %s (%d)",
1423 __FUNCTION__, strerror(-res), res);
1424 return res;
1425 }
1426
1427 ALOGV("%s: Allocated reprocess stream id %d based on stream %d",
1428 __FUNCTION__, id, outputStream->getId());
1429
1430 mId = id;
1431
1432 mState = ACTIVE;
1433
1434 return OK;
1435}
1436
1437status_t Camera2Device::ReprocessStreamAdapter::release() {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001438 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001439 status_t res;
1440 ALOGV("%s: Releasing stream %d", __FUNCTION__, mId);
1441 if (mState >= ACTIVE) {
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001442 res = mHal2Device->ops->release_reprocess_stream(mHal2Device, mId);
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001443 if (res != OK) {
1444 ALOGE("%s: Unable to release stream %d",
1445 __FUNCTION__, mId);
1446 return res;
1447 }
1448 }
1449
1450 List<QueueEntry>::iterator s;
1451 for (s = mQueue.begin(); s != mQueue.end(); s++) {
1452 sp<BufferReleasedListener> listener = s->releaseListener.promote();
1453 if (listener != 0) listener->onBufferReleased(s->handle);
1454 }
1455 for (s = mInFlightQueue.begin(); s != mInFlightQueue.end(); s++) {
1456 sp<BufferReleasedListener> listener = s->releaseListener.promote();
1457 if (listener != 0) listener->onBufferReleased(s->handle);
1458 }
1459 mQueue.clear();
1460 mInFlightQueue.clear();
1461
1462 mState = RELEASED;
1463 return OK;
1464}
1465
1466status_t Camera2Device::ReprocessStreamAdapter::pushIntoStream(
1467 buffer_handle_t *handle, const wp<BufferReleasedListener> &releaseListener) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001468 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001469 // TODO: Some error checking here would be nice
1470 ALOGV("%s: Pushing buffer %p to stream", __FUNCTION__, (void*)(*handle));
1471
1472 QueueEntry entry;
1473 entry.handle = handle;
1474 entry.releaseListener = releaseListener;
1475 mQueue.push_back(entry);
1476 return OK;
1477}
1478
1479status_t Camera2Device::ReprocessStreamAdapter::dump(int fd,
Igor Murashkinebe3f692012-10-12 16:56:11 -07001480 const Vector<String16>& /*args*/) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001481 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001482 String8 result =
1483 String8::format(" Reprocess stream %d: %d x %d, fmt 0x%x\n",
1484 mId, mWidth, mHeight, mFormat);
1485 result.appendFormat(" acquired buffers: %d\n",
1486 mActiveBuffers);
1487 result.appendFormat(" frame count: %d\n",
1488 mFrameCount);
1489 write(fd, result.string(), result.size());
1490 return OK;
1491}
1492
1493const camera2_stream_in_ops *Camera2Device::ReprocessStreamAdapter::getStreamOps() {
1494 return static_cast<camera2_stream_in_ops *>(this);
1495}
1496
1497int Camera2Device::ReprocessStreamAdapter::acquire_buffer(
1498 const camera2_stream_in_ops_t *w,
1499 buffer_handle_t** buffer) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001500 ATRACE_CALL();
Igor Murashkinebe3f692012-10-12 16:56:11 -07001501
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001502 ReprocessStreamAdapter* stream =
1503 const_cast<ReprocessStreamAdapter*>(
1504 static_cast<const ReprocessStreamAdapter*>(w));
1505 if (stream->mState != ACTIVE) {
1506 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
1507 return INVALID_OPERATION;
1508 }
1509
1510 if (stream->mQueue.empty()) {
1511 *buffer = NULL;
1512 return OK;
1513 }
1514
1515 QueueEntry &entry = *(stream->mQueue.begin());
1516
1517 *buffer = entry.handle;
1518
1519 stream->mInFlightQueue.push_back(entry);
1520 stream->mQueue.erase(stream->mQueue.begin());
1521
1522 stream->mActiveBuffers++;
1523
1524 ALOGV("Stream %d acquire: Buffer %p acquired", stream->mId,
1525 (void*)(**buffer));
1526 return OK;
1527}
1528
1529int Camera2Device::ReprocessStreamAdapter::release_buffer(
1530 const camera2_stream_in_ops_t* w,
1531 buffer_handle_t* buffer) {
Eino-Ville Talvala852c3812012-09-24 09:46:53 -07001532 ATRACE_CALL();
Eino-Ville Talvala69230df2012-08-29 17:37:16 -07001533 ReprocessStreamAdapter *stream =
1534 const_cast<ReprocessStreamAdapter*>(
1535 static_cast<const ReprocessStreamAdapter*>(w) );
1536 stream->mFrameCount++;
1537 ALOGV("Reprocess stream %d release: Frame %d (%p)",
1538 stream->mId, stream->mFrameCount, (void*)*buffer);
1539 int state = stream->mState;
1540 if (state != ACTIVE) {
1541 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1542 return INVALID_OPERATION;
1543 }
1544 stream->mActiveBuffers--;
1545
1546 List<QueueEntry>::iterator s;
1547 for (s = stream->mInFlightQueue.begin(); s != stream->mInFlightQueue.end(); s++) {
1548 if ( s->handle == buffer ) break;
1549 }
1550 if (s == stream->mInFlightQueue.end()) {
1551 ALOGE("%s: Can't find buffer %p in in-flight list!", __FUNCTION__,
1552 buffer);
1553 return INVALID_OPERATION;
1554 }
1555
1556 sp<BufferReleasedListener> listener = s->releaseListener.promote();
1557 if (listener != 0) {
1558 listener->onBufferReleased(s->handle);
1559 } else {
1560 ALOGE("%s: Can't free buffer - missing listener", __FUNCTION__);
1561 }
1562 stream->mInFlightQueue.erase(s);
1563
1564 return OK;
1565}
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001566
1567}; // namespace android