blob: 49f0795fe464eff96cb4511472f81366c85ccf3b [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 Talvala4bb81182012-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
28#include <utils/Log.h>
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -070029#include <utils/Trace.h>
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070030#include "Camera2Device.h"
31
32namespace android {
33
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070034Camera2Device::Camera2Device(int id):
35 mId(id),
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070036 mDevice(NULL)
37{
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -070038 ATRACE_CALL();
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -070039 ALOGV("%s: Created device for camera %d", __FUNCTION__, id);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070040}
41
42Camera2Device::~Camera2Device()
43{
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -070044 ATRACE_CALL();
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -070045 disconnect();
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070046}
47
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070048status_t Camera2Device::initialize(camera_module_t *module)
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070049{
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -070050 ATRACE_CALL();
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -070051 ALOGV("%s: Initializing device for camera %d", __FUNCTION__, mId);
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -070052 if (mDevice != NULL) {
53 ALOGE("%s: Already initialized!", __FUNCTION__);
54 return INVALID_OPERATION;
55 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -070056
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070057 status_t res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070058 char name[10];
59 snprintf(name, sizeof(name), "%d", mId);
60
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -070061 camera2_device_t *device;
62
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070063 res = module->common.methods->open(&module->common, name,
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -070064 reinterpret_cast<hw_device_t**>(&device));
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070065
66 if (res != OK) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070067 ALOGE("%s: Could not open camera %d: %s (%d)", __FUNCTION__,
68 mId, strerror(-res), res);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070069 return res;
70 }
71
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -070072 if (device->common.version != CAMERA_DEVICE_API_VERSION_2_0) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070073 ALOGE("%s: Could not open camera %d: "
74 "Camera device is not version %x, reports %x instead",
75 __FUNCTION__, mId, CAMERA_DEVICE_API_VERSION_2_0,
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -070076 device->common.version);
77 device->common.close(&device->common);
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -070078 return BAD_VALUE;
79 }
80
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070081 camera_info info;
82 res = module->get_camera_info(mId, &info);
83 if (res != OK ) return res;
84
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -070085 if (info.device_version != device->common.version) {
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070086 ALOGE("%s: HAL reporting mismatched camera_info version (%x)"
87 " and device version (%x).", __FUNCTION__,
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -070088 device->common.version, info.device_version);
89 device->common.close(&device->common);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -070090 return BAD_VALUE;
91 }
92
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -070093 res = mRequestQueue.setConsumerDevice(device);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -070094 if (res != OK) {
95 ALOGE("%s: Camera %d: Unable to connect request queue to device: %s (%d)",
96 __FUNCTION__, mId, strerror(-res), res);
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -070097 device->common.close(&device->common);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -070098 return res;
99 }
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -0700100 res = mFrameQueue.setProducerDevice(device);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700101 if (res != OK) {
102 ALOGE("%s: Camera %d: Unable to connect frame queue to device: %s (%d)",
103 __FUNCTION__, mId, strerror(-res), res);
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -0700104 device->common.close(&device->common);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700105 return res;
106 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700107
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -0700108 res = device->ops->get_metadata_vendor_tag_ops(device, &mVendorTagOps);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700109 if (res != OK ) {
110 ALOGE("%s: Camera %d: Unable to retrieve tag ops from device: %s (%d)",
111 __FUNCTION__, mId, strerror(-res), res);
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -0700112 device->common.close(&device->common);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700113 return res;
114 }
Shuzhen Wang092fe442012-08-31 10:24:22 -0700115 res = set_camera_metadata_vendor_tag_ops(mVendorTagOps);
116 if (res != OK) {
117 ALOGE("%s: Camera %d: Unable to set tag ops: %s (%d)",
118 __FUNCTION__, mId, strerror(-res), res);
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -0700119 device->common.close(&device->common);
Shuzhen Wang092fe442012-08-31 10:24:22 -0700120 return res;
121 }
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -0700122 res = device->ops->set_notify_callback(device, notificationCallback,
123 NULL);
124 if (res != OK) {
125 ALOGE("%s: Camera %d: Unable to initialize notification callback!",
126 __FUNCTION__, mId);
127 device->common.close(&device->common);
128 return res;
129 }
130
131 mDeviceInfo = info.static_camera_characteristics;
132 mDevice = device;
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700133
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -0700134 return OK;
135}
136
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -0700137status_t Camera2Device::disconnect() {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700138 ATRACE_CALL();
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -0700139 status_t res = OK;
140 if (mDevice) {
141 ALOGV("%s: Closing device for camera %d", __FUNCTION__, mId);
142
143 int inProgressCount = mDevice->ops->get_in_progress_count(mDevice);
144 if (inProgressCount > 0) {
145 ALOGW("%s: Closing camera device %d with %d requests in flight!",
146 __FUNCTION__, mId, inProgressCount);
147 }
148 mStreams.clear();
149 res = mDevice->common.close(&mDevice->common);
150 if (res != OK) {
151 ALOGE("%s: Could not close camera %d: %s (%d)",
152 __FUNCTION__,
153 mId, strerror(-res), res);
154 }
155 mDevice = NULL;
156 ALOGV("%s: Shutdown complete", __FUNCTION__);
157 }
158 return res;
159}
160
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700161status_t Camera2Device::dump(int fd, const Vector<String16>& args) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700162 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700163 String8 result;
Eino-Ville Talvala97197152012-08-06 14:25:19 -0700164 int detailLevel = 0;
165 int n = args.size();
166 String16 detailOption("-d");
167 for (int i = 0; i + 1 < n; i++) {
168 if (args[i] == detailOption) {
169 String8 levelStr(args[i+1]);
170 detailLevel = atoi(levelStr.string());
171 }
172 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700173
Eino-Ville Talvala603b12e2012-08-08 09:25:58 -0700174 result.appendFormat(" Camera2Device[%d] dump (detail level %d):\n",
175 mId, detailLevel);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700176
Eino-Ville Talvala97197152012-08-06 14:25:19 -0700177 if (detailLevel > 0) {
178 result = " Request queue contents:\n";
179 write(fd, result.string(), result.size());
180 mRequestQueue.dump(fd, args);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700181
Eino-Ville Talvala97197152012-08-06 14:25:19 -0700182 result = " Frame queue contents:\n";
183 write(fd, result.string(), result.size());
184 mFrameQueue.dump(fd, args);
185 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700186
187 result = " Active streams:\n";
188 write(fd, result.string(), result.size());
189 for (StreamList::iterator s = mStreams.begin(); s != mStreams.end(); s++) {
190 (*s)->dump(fd, args);
191 }
192
193 result = " HAL device dump:\n";
194 write(fd, result.string(), result.size());
195
196 status_t res;
197 res = mDevice->ops->dump(mDevice, fd);
198
199 return res;
200}
201
Eino-Ville Talvala2e19c3c2012-08-26 09:29:28 -0700202const camera2::CameraMetadata& Camera2Device::info() const {
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700203 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700204
205 return mDeviceInfo;
206}
207
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700208status_t Camera2Device::capture(CameraMetadata &request) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700209 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700210 ALOGV("%s: E", __FUNCTION__);
211
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700212 mRequestQueue.enqueue(request.release());
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700213 return OK;
214}
215
216
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700217status_t Camera2Device::setStreamingRequest(const CameraMetadata &request) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700218 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700219 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700220 CameraMetadata streamRequest(request);
221 return mRequestQueue.setStreamSlot(streamRequest.release());
222}
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700223
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700224status_t Camera2Device::clearStreamingRequest() {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700225 ATRACE_CALL();
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700226 return mRequestQueue.setStreamSlot(NULL);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700227}
228
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700229status_t Camera2Device::createStream(sp<ANativeWindow> consumer,
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700230 uint32_t width, uint32_t height, int format, size_t size, int *id) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700231 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700232 status_t res;
233 ALOGV("%s: E", __FUNCTION__);
234
235 sp<StreamAdapter> stream = new StreamAdapter(mDevice);
236
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700237 res = stream->connectToDevice(consumer, width, height, format, size);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700238 if (res != OK) {
239 ALOGE("%s: Camera %d: Unable to create stream (%d x %d, format %x):"
240 "%s (%d)",
241 __FUNCTION__, mId, width, height, format, strerror(-res), res);
242 return res;
243 }
244
245 *id = stream->getId();
246
247 mStreams.push_back(stream);
248 return OK;
249}
250
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700251status_t Camera2Device::createReprocessStreamFromStream(int outputId, int *id) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700252 ATRACE_CALL();
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700253 status_t res;
254 ALOGV("%s: E", __FUNCTION__);
255
256 bool found = false;
257 StreamList::iterator streamI;
258 for (streamI = mStreams.begin();
259 streamI != mStreams.end(); streamI++) {
260 if ((*streamI)->getId() == outputId) {
261 found = true;
262 break;
263 }
264 }
265 if (!found) {
266 ALOGE("%s: Camera %d: Output stream %d doesn't exist; can't create "
267 "reprocess stream from it!", __FUNCTION__, mId, outputId);
268 return BAD_VALUE;
269 }
270
271 sp<ReprocessStreamAdapter> stream = new ReprocessStreamAdapter(mDevice);
272
273 res = stream->connectToDevice((*streamI));
274 if (res != OK) {
275 ALOGE("%s: Camera %d: Unable to create reprocessing stream from "\
276 "stream %d: %s (%d)", __FUNCTION__, mId, outputId,
277 strerror(-res), res);
278 return res;
279 }
280
281 *id = stream->getId();
282
283 mReprocessStreams.push_back(stream);
284 return OK;
285}
286
287
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700288status_t Camera2Device::getStreamInfo(int id,
289 uint32_t *width, uint32_t *height, uint32_t *format) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700290 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700291 ALOGV("%s: E", __FUNCTION__);
292 bool found = false;
293 StreamList::iterator streamI;
294 for (streamI = mStreams.begin();
295 streamI != mStreams.end(); streamI++) {
296 if ((*streamI)->getId() == id) {
297 found = true;
298 break;
299 }
300 }
301 if (!found) {
302 ALOGE("%s: Camera %d: Stream %d does not exist",
303 __FUNCTION__, mId, id);
304 return BAD_VALUE;
305 }
306
307 if (width) *width = (*streamI)->getWidth();
308 if (height) *height = (*streamI)->getHeight();
309 if (format) *format = (*streamI)->getFormat();
310
311 return OK;
312}
313
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -0700314status_t Camera2Device::setStreamTransform(int id,
315 int transform) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700316 ATRACE_CALL();
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -0700317 ALOGV("%s: E", __FUNCTION__);
318 bool found = false;
319 StreamList::iterator streamI;
320 for (streamI = mStreams.begin();
321 streamI != mStreams.end(); streamI++) {
322 if ((*streamI)->getId() == id) {
323 found = true;
324 break;
325 }
326 }
327 if (!found) {
328 ALOGE("%s: Camera %d: Stream %d does not exist",
329 __FUNCTION__, mId, id);
330 return BAD_VALUE;
331 }
332
333 return (*streamI)->setTransform(transform);
334}
335
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700336status_t Camera2Device::deleteStream(int id) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700337 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700338 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700339 bool found = false;
340 for (StreamList::iterator streamI = mStreams.begin();
341 streamI != mStreams.end(); streamI++) {
342 if ((*streamI)->getId() == id) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700343 status_t res = (*streamI)->release();
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700344 if (res != OK) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700345 ALOGE("%s: Unable to release stream %d from HAL device: "
Eino-Ville Talvala4ecfec32012-06-12 17:13:48 -0700346 "%s (%d)", __FUNCTION__, id, strerror(-res), res);
347 return res;
348 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700349 mStreams.erase(streamI);
350 found = true;
351 break;
352 }
353 }
354 if (!found) {
355 ALOGE("%s: Camera %d: Unable to find stream %d to delete",
356 __FUNCTION__, mId, id);
357 return BAD_VALUE;
358 }
359 return OK;
360}
361
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700362status_t Camera2Device::deleteReprocessStream(int id) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700363 ATRACE_CALL();
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700364 ALOGV("%s: E", __FUNCTION__);
365 bool found = false;
366 for (ReprocessStreamList::iterator streamI = mReprocessStreams.begin();
367 streamI != mReprocessStreams.end(); streamI++) {
368 if ((*streamI)->getId() == id) {
369 status_t res = (*streamI)->release();
370 if (res != OK) {
371 ALOGE("%s: Unable to release reprocess stream %d from "
372 "HAL device: %s (%d)", __FUNCTION__, id,
373 strerror(-res), res);
374 return res;
375 }
376 mReprocessStreams.erase(streamI);
377 found = true;
378 break;
379 }
380 }
381 if (!found) {
382 ALOGE("%s: Camera %d: Unable to find stream %d to delete",
383 __FUNCTION__, mId, id);
384 return BAD_VALUE;
385 }
386 return OK;
387}
388
389
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700390status_t Camera2Device::createDefaultRequest(int templateId,
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700391 CameraMetadata *request) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700392 ATRACE_CALL();
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700393 status_t err;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700394 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700395 camera_metadata_t *rawRequest;
396 err = mDevice->ops->construct_default_request(
397 mDevice, templateId, &rawRequest);
398 request->acquire(rawRequest);
399 return err;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700400}
401
402status_t Camera2Device::waitUntilDrained() {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700403 ATRACE_CALL();
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700404 static const uint32_t kSleepTime = 50000; // 50 ms
405 static const uint32_t kMaxSleepTime = 10000000; // 10 s
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -0700406 ALOGV("%s: Camera %d: Starting wait", __FUNCTION__, mId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700407 if (mRequestQueue.getBufferCount() ==
408 CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS) return INVALID_OPERATION;
409
410 // TODO: Set up notifications from HAL, instead of sleeping here
411 uint32_t totalTime = 0;
412 while (mDevice->ops->get_in_progress_count(mDevice) > 0) {
413 usleep(kSleepTime);
414 totalTime += kSleepTime;
415 if (totalTime > kMaxSleepTime) {
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -0700416 ALOGE("%s: Waited %d us, %d requests still in flight", __FUNCTION__,
417 mDevice->ops->get_in_progress_count(mDevice), totalTime);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700418 return TIMED_OUT;
419 }
420 }
Eino-Ville Talvala98bb82d2012-09-20 14:44:20 -0700421 ALOGV("%s: Camera %d: HAL is idle", __FUNCTION__, mId);
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700422 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700423}
424
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700425status_t Camera2Device::setNotifyCallback(NotificationListener *listener) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700426 ATRACE_CALL();
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700427 status_t res;
428 res = mDevice->ops->set_notify_callback(mDevice, notificationCallback,
429 reinterpret_cast<void*>(listener) );
430 if (res != OK) {
431 ALOGE("%s: Unable to set notification callback!", __FUNCTION__);
432 }
433 return res;
434}
435
436void Camera2Device::notificationCallback(int32_t msg_type,
437 int32_t ext1,
438 int32_t ext2,
439 int32_t ext3,
440 void *user) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700441 ATRACE_CALL();
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700442 NotificationListener *listener = reinterpret_cast<NotificationListener*>(user);
443 ALOGV("%s: Notification %d, arguments %d, %d, %d", __FUNCTION__, msg_type,
444 ext1, ext2, ext3);
445 if (listener != NULL) {
446 switch (msg_type) {
447 case CAMERA2_MSG_ERROR:
448 listener->notifyError(ext1, ext2, ext3);
449 break;
450 case CAMERA2_MSG_SHUTTER: {
451 nsecs_t timestamp = (nsecs_t)ext2 | ((nsecs_t)(ext3) << 32 );
452 listener->notifyShutter(ext1, timestamp);
453 break;
454 }
455 case CAMERA2_MSG_AUTOFOCUS:
456 listener->notifyAutoFocus(ext1, ext2);
457 break;
458 case CAMERA2_MSG_AUTOEXPOSURE:
459 listener->notifyAutoExposure(ext1, ext2);
460 break;
461 case CAMERA2_MSG_AUTOWB:
462 listener->notifyAutoWhitebalance(ext1, ext2);
463 break;
464 default:
465 ALOGE("%s: Unknown notification %d (arguments %d, %d, %d)!",
466 __FUNCTION__, msg_type, ext1, ext2, ext3);
467 }
468 }
469}
470
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -0700471status_t Camera2Device::waitForNextFrame(nsecs_t timeout) {
472 return mFrameQueue.waitForBuffer(timeout);
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700473}
474
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700475status_t Camera2Device::getNextFrame(CameraMetadata *frame) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700476 ATRACE_CALL();
Eino-Ville Talvalacab96a42012-08-24 11:29:22 -0700477 status_t res;
478 camera_metadata_t *rawFrame;
479 res = mFrameQueue.dequeue(&rawFrame);
480 if (rawFrame == NULL) {
481 return NOT_ENOUGH_DATA;
482 } else if (res == OK) {
483 frame->acquire(rawFrame);
484 }
485 return res;
Eino-Ville Talvala8ce89d92012-08-10 08:40:26 -0700486}
487
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700488status_t Camera2Device::triggerAutofocus(uint32_t id) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700489 ATRACE_CALL();
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700490 status_t res;
491 ALOGV("%s: Triggering autofocus, id %d", __FUNCTION__, id);
492 res = mDevice->ops->trigger_action(mDevice,
493 CAMERA2_TRIGGER_AUTOFOCUS, id, 0);
494 if (res != OK) {
495 ALOGE("%s: Error triggering autofocus (id %d)",
496 __FUNCTION__, id);
497 }
498 return res;
499}
500
501status_t Camera2Device::triggerCancelAutofocus(uint32_t id) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700502 ATRACE_CALL();
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700503 status_t res;
504 ALOGV("%s: Canceling autofocus, id %d", __FUNCTION__, id);
505 res = mDevice->ops->trigger_action(mDevice,
506 CAMERA2_TRIGGER_CANCEL_AUTOFOCUS, id, 0);
507 if (res != OK) {
508 ALOGE("%s: Error canceling autofocus (id %d)",
509 __FUNCTION__, id);
510 }
511 return res;
512}
513
514status_t Camera2Device::triggerPrecaptureMetering(uint32_t id) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700515 ATRACE_CALL();
Eino-Ville Talvala174181e2012-08-03 13:53:39 -0700516 status_t res;
517 ALOGV("%s: Triggering precapture metering, id %d", __FUNCTION__, id);
518 res = mDevice->ops->trigger_action(mDevice,
519 CAMERA2_TRIGGER_PRECAPTURE_METERING, id, 0);
520 if (res != OK) {
521 ALOGE("%s: Error triggering precapture metering (id %d)",
522 __FUNCTION__, id);
523 }
524 return res;
525}
526
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700527status_t Camera2Device::pushReprocessBuffer(int reprocessStreamId,
528 buffer_handle_t *buffer, wp<BufferReleasedListener> listener) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700529 ATRACE_CALL();
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -0700530 ALOGV("%s: E", __FUNCTION__);
531 bool found = false;
532 status_t res = OK;
533 for (ReprocessStreamList::iterator streamI = mReprocessStreams.begin();
534 streamI != mReprocessStreams.end(); streamI++) {
535 if ((*streamI)->getId() == reprocessStreamId) {
536 res = (*streamI)->pushIntoStream(buffer, listener);
537 if (res != OK) {
538 ALOGE("%s: Unable to push buffer to reprocess stream %d: %s (%d)",
539 __FUNCTION__, reprocessStreamId, strerror(-res), res);
540 return res;
541 }
542 found = true;
543 break;
544 }
545 }
546 if (!found) {
547 ALOGE("%s: Camera %d: Unable to find reprocess stream %d",
548 __FUNCTION__, mId, reprocessStreamId);
549 res = BAD_VALUE;
550 }
551 return res;
552}
553
Eino-Ville Talvala160d4af2012-08-03 09:40:16 -0700554/**
555 * Camera2Device::NotificationListener
556 */
557
558Camera2Device::NotificationListener::~NotificationListener() {
559}
560
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700561/**
562 * Camera2Device::MetadataQueue
563 */
564
565Camera2Device::MetadataQueue::MetadataQueue():
566 mDevice(NULL),
567 mFrameCount(0),
568 mCount(0),
569 mStreamSlotCount(0),
Eino-Ville Talvalac8474b62012-08-24 16:30:44 -0700570 mSignalConsumer(true)
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700571{
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700572 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700573 camera2_request_queue_src_ops::dequeue_request = consumer_dequeue;
574 camera2_request_queue_src_ops::request_count = consumer_buffer_count;
575 camera2_request_queue_src_ops::free_request = consumer_free;
576
577 camera2_frame_queue_dst_ops::dequeue_frame = producer_dequeue;
578 camera2_frame_queue_dst_ops::cancel_frame = producer_cancel;
579 camera2_frame_queue_dst_ops::enqueue_frame = producer_enqueue;
580}
581
582Camera2Device::MetadataQueue::~MetadataQueue() {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700583 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700584 Mutex::Autolock l(mMutex);
585 freeBuffers(mEntries.begin(), mEntries.end());
586 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
587}
588
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700589// Connect to camera2 HAL as consumer (input requests/reprocessing)
590status_t Camera2Device::MetadataQueue::setConsumerDevice(camera2_device_t *d) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700591 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700592 status_t res;
593 res = d->ops->set_request_queue_src_ops(d,
594 this);
595 if (res != OK) return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700596 mDevice = d;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700597 return OK;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700598}
599
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700600status_t Camera2Device::MetadataQueue::setProducerDevice(camera2_device_t *d) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700601 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700602 status_t res;
603 res = d->ops->set_frame_queue_dst_ops(d,
604 this);
605 return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700606}
607
608// Real interfaces
609status_t Camera2Device::MetadataQueue::enqueue(camera_metadata_t *buf) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700610 ATRACE_CALL();
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700611 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700612 Mutex::Autolock l(mMutex);
613
614 mCount++;
615 mEntries.push_back(buf);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700616
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700617 return signalConsumerLocked();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700618}
619
620int Camera2Device::MetadataQueue::getBufferCount() {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700621 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700622 Mutex::Autolock l(mMutex);
623 if (mStreamSlotCount > 0) {
624 return CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS;
625 }
626 return mCount;
627}
628
629status_t Camera2Device::MetadataQueue::dequeue(camera_metadata_t **buf,
630 bool incrementCount)
631{
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700632 ATRACE_CALL();
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700633 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700634 status_t res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700635 Mutex::Autolock l(mMutex);
636
637 if (mCount == 0) {
638 if (mStreamSlotCount == 0) {
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700639 ALOGVV("%s: Empty", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700640 *buf = NULL;
641 mSignalConsumer = true;
642 return OK;
643 }
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700644 ALOGVV("%s: Streaming %d frames to queue", __FUNCTION__,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700645 mStreamSlotCount);
646
647 for (List<camera_metadata_t*>::iterator slotEntry = mStreamSlot.begin();
648 slotEntry != mStreamSlot.end();
649 slotEntry++ ) {
650 size_t entries = get_camera_metadata_entry_count(*slotEntry);
651 size_t dataBytes = get_camera_metadata_data_count(*slotEntry);
652
653 camera_metadata_t *copy =
654 allocate_camera_metadata(entries, dataBytes);
655 append_camera_metadata(copy, *slotEntry);
656 mEntries.push_back(copy);
657 }
658 mCount = mStreamSlotCount;
659 }
Eino-Ville Talvala2c08dc62012-06-15 12:49:21 -0700660 ALOGVV("MetadataQueue: deque (%d buffers)", mCount);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700661 camera_metadata_t *b = *(mEntries.begin());
662 mEntries.erase(mEntries.begin());
663
664 if (incrementCount) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700665 ATRACE_INT("cam2_request", mFrameCount);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700666 camera_metadata_entry_t frameCount;
667 res = find_camera_metadata_entry(b,
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700668 ANDROID_REQUEST_FRAME_COUNT,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700669 &frameCount);
670 if (res != OK) {
671 ALOGE("%s: Unable to add frame count: %s (%d)",
672 __FUNCTION__, strerror(-res), res);
673 } else {
674 *frameCount.data.i32 = mFrameCount;
675 }
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700676 mFrameCount++;
677 }
678
679 *buf = b;
680 mCount--;
681
682 return OK;
683}
684
685status_t Camera2Device::MetadataQueue::waitForBuffer(nsecs_t timeout)
686{
687 Mutex::Autolock l(mMutex);
688 status_t res;
689 while (mCount == 0) {
690 res = notEmpty.waitRelative(mMutex,timeout);
691 if (res != OK) return res;
692 }
693 return OK;
694}
695
696status_t Camera2Device::MetadataQueue::setStreamSlot(camera_metadata_t *buf)
697{
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700698 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700699 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700700 Mutex::Autolock l(mMutex);
701 if (buf == NULL) {
702 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
703 mStreamSlotCount = 0;
704 return OK;
705 }
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700706 camera_metadata_t *buf2 = clone_camera_metadata(buf);
707 if (!buf2) {
708 ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__);
709 return NO_MEMORY;
710 }
711
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700712 if (mStreamSlotCount > 1) {
713 List<camera_metadata_t*>::iterator deleter = ++mStreamSlot.begin();
714 freeBuffers(++mStreamSlot.begin(), mStreamSlot.end());
715 mStreamSlotCount = 1;
716 }
717 if (mStreamSlotCount == 1) {
718 free_camera_metadata( *(mStreamSlot.begin()) );
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700719 *(mStreamSlot.begin()) = buf2;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700720 } else {
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700721 mStreamSlot.push_front(buf2);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700722 mStreamSlotCount = 1;
723 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700724 return signalConsumerLocked();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700725}
726
727status_t Camera2Device::MetadataQueue::setStreamSlot(
728 const List<camera_metadata_t*> &bufs)
729{
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700730 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700731 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700732 Mutex::Autolock l(mMutex);
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700733 status_t res;
734
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700735 if (mStreamSlotCount > 0) {
736 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
737 }
Eino-Ville Talvala6ed1ed12012-06-07 10:46:38 -0700738 mStreamSlotCount = 0;
739 for (List<camera_metadata_t*>::const_iterator r = bufs.begin();
740 r != bufs.end(); r++) {
741 camera_metadata_t *r2 = clone_camera_metadata(*r);
742 if (!r2) {
743 ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__);
744 return NO_MEMORY;
745 }
746 mStreamSlot.push_back(r2);
747 mStreamSlotCount++;
748 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700749 return signalConsumerLocked();
750}
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700751
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700752status_t Camera2Device::MetadataQueue::dump(int fd,
753 const Vector<String16>& args) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700754 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700755 String8 result;
756 status_t notLocked;
757 notLocked = mMutex.tryLock();
758 if (notLocked) {
759 result.append(" (Unable to lock queue mutex)\n");
760 }
761 result.appendFormat(" Current frame number: %d\n", mFrameCount);
762 if (mStreamSlotCount == 0) {
763 result.append(" Stream slot: Empty\n");
764 write(fd, result.string(), result.size());
765 } else {
766 result.appendFormat(" Stream slot: %d entries\n",
767 mStreamSlot.size());
768 int i = 0;
769 for (List<camera_metadata_t*>::iterator r = mStreamSlot.begin();
770 r != mStreamSlot.end(); r++) {
771 result = String8::format(" Stream slot buffer %d:\n", i);
772 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700773 dump_indented_camera_metadata(*r, fd, 2, 10);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700774 i++;
775 }
776 }
777 if (mEntries.size() == 0) {
778 result = " Main queue is empty\n";
779 write(fd, result.string(), result.size());
780 } else {
781 result = String8::format(" Main queue has %d entries:\n",
782 mEntries.size());
783 int i = 0;
784 for (List<camera_metadata_t*>::iterator r = mEntries.begin();
785 r != mEntries.end(); r++) {
786 result = String8::format(" Queue entry %d:\n", i);
787 write(fd, result.string(), result.size());
Eino-Ville Talvala428b77a2012-07-30 09:55:30 -0700788 dump_indented_camera_metadata(*r, fd, 2, 10);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700789 i++;
790 }
791 }
792
793 if (notLocked == 0) {
794 mMutex.unlock();
795 }
796
797 return OK;
798}
799
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700800status_t Camera2Device::MetadataQueue::signalConsumerLocked() {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700801 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700802 status_t res = OK;
803 notEmpty.signal();
804 if (mSignalConsumer && mDevice != NULL) {
805 mSignalConsumer = false;
806
807 mMutex.unlock();
808 ALOGV("%s: Signaling consumer", __FUNCTION__);
809 res = mDevice->ops->notify_request_queue_not_empty(mDevice);
810 mMutex.lock();
811 }
812 return res;
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700813}
814
815status_t Camera2Device::MetadataQueue::freeBuffers(
816 List<camera_metadata_t*>::iterator start,
817 List<camera_metadata_t*>::iterator end)
818{
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700819 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700820 while (start != end) {
821 free_camera_metadata(*start);
822 start = mStreamSlot.erase(start);
823 }
824 return OK;
825}
826
827Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
828 const camera2_request_queue_src_ops_t *q)
829{
830 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
831 return const_cast<MetadataQueue*>(cmq);
832}
833
834Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
835 const camera2_frame_queue_dst_ops_t *q)
836{
837 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
838 return const_cast<MetadataQueue*>(cmq);
839}
840
841int Camera2Device::MetadataQueue::consumer_buffer_count(
842 const camera2_request_queue_src_ops_t *q)
843{
844 MetadataQueue *queue = getInstance(q);
845 return queue->getBufferCount();
846}
847
848int Camera2Device::MetadataQueue::consumer_dequeue(
849 const camera2_request_queue_src_ops_t *q,
850 camera_metadata_t **buffer)
851{
852 MetadataQueue *queue = getInstance(q);
853 return queue->dequeue(buffer, true);
854}
855
856int Camera2Device::MetadataQueue::consumer_free(
857 const camera2_request_queue_src_ops_t *q,
858 camera_metadata_t *old_buffer)
859{
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700860 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700861 MetadataQueue *queue = getInstance(q);
862 free_camera_metadata(old_buffer);
863 return OK;
864}
865
866int Camera2Device::MetadataQueue::producer_dequeue(
867 const camera2_frame_queue_dst_ops_t *q,
868 size_t entries, size_t bytes,
869 camera_metadata_t **buffer)
870{
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700871 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700872 camera_metadata_t *new_buffer =
873 allocate_camera_metadata(entries, bytes);
874 if (new_buffer == NULL) return NO_MEMORY;
875 *buffer = new_buffer;
876 return OK;
877}
878
879int Camera2Device::MetadataQueue::producer_cancel(
880 const camera2_frame_queue_dst_ops_t *q,
881 camera_metadata_t *old_buffer)
882{
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700883 ATRACE_CALL();
Eino-Ville Talvalaf69c70d2012-05-20 15:59:14 -0700884 free_camera_metadata(old_buffer);
885 return OK;
886}
887
888int Camera2Device::MetadataQueue::producer_enqueue(
889 const camera2_frame_queue_dst_ops_t *q,
890 camera_metadata_t *filled_buffer)
891{
892 MetadataQueue *queue = getInstance(q);
893 return queue->enqueue(filled_buffer);
894}
895
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700896/**
897 * Camera2Device::StreamAdapter
898 */
899
900#ifndef container_of
901#define container_of(ptr, type, member) \
902 (type *)((char*)(ptr) - offsetof(type, member))
903#endif
904
905Camera2Device::StreamAdapter::StreamAdapter(camera2_device_t *d):
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700906 mState(RELEASED),
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700907 mDevice(d),
908 mId(-1),
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -0700909 mWidth(0), mHeight(0), mFormat(0), mSize(0), mUsage(0),
910 mMaxProducerBuffers(0), mMaxConsumerBuffers(0),
911 mTotalBuffers(0),
912 mFormatRequested(0),
913 mActiveBuffers(0),
914 mFrameCount(0),
915 mLastTimestamp(0)
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700916{
917 camera2_stream_ops::dequeue_buffer = dequeue_buffer;
918 camera2_stream_ops::enqueue_buffer = enqueue_buffer;
919 camera2_stream_ops::cancel_buffer = cancel_buffer;
920 camera2_stream_ops::set_crop = set_crop;
921}
922
923Camera2Device::StreamAdapter::~StreamAdapter() {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700924 ATRACE_CALL();
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700925 if (mState != RELEASED) {
926 release();
927 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700928}
929
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700930status_t Camera2Device::StreamAdapter::connectToDevice(
931 sp<ANativeWindow> consumer,
932 uint32_t width, uint32_t height, int format, size_t size) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -0700933 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700934 status_t res;
Eino-Ville Talvala9e4c3db2012-07-20 11:07:52 -0700935 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700936
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700937 if (mState != RELEASED) return INVALID_OPERATION;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700938 if (consumer == NULL) {
939 ALOGE("%s: Null consumer passed to stream adapter", __FUNCTION__);
940 return BAD_VALUE;
941 }
942
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700943 ALOGV("%s: New stream parameters %d x %d, format 0x%x, size %d",
944 __FUNCTION__, width, height, format, size);
945
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700946 mConsumerInterface = consumer;
947 mWidth = width;
948 mHeight = height;
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -0700949 mSize = (format == HAL_PIXEL_FORMAT_BLOB) ? size : 0;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700950 mFormatRequested = format;
951
952 // Allocate device-side stream interface
953
954 uint32_t id;
955 uint32_t formatActual;
956 uint32_t usage;
957 uint32_t maxBuffers = 2;
958 res = mDevice->ops->allocate_stream(mDevice,
959 mWidth, mHeight, mFormatRequested, getStreamOps(),
960 &id, &formatActual, &usage, &maxBuffers);
961 if (res != OK) {
962 ALOGE("%s: Device stream allocation failed: %s (%d)",
963 __FUNCTION__, strerror(-res), res);
964 return res;
965 }
966
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -0700967 ALOGV("%s: Allocated stream id %d, actual format 0x%x, "
968 "usage 0x%x, producer wants %d buffers", __FUNCTION__,
969 id, formatActual, usage, maxBuffers);
970
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -0700971 mId = id;
972 mFormat = formatActual;
973 mUsage = usage;
974 mMaxProducerBuffers = maxBuffers;
975
976 mState = ALLOCATED;
977
978 // Configure consumer-side ANativeWindow interface
979 res = native_window_api_connect(mConsumerInterface.get(),
980 NATIVE_WINDOW_API_CAMERA);
981 if (res != OK) {
982 ALOGE("%s: Unable to connect to native window for stream %d",
983 __FUNCTION__, mId);
984
985 return res;
986 }
987
988 mState = CONNECTED;
989
990 res = native_window_set_usage(mConsumerInterface.get(), mUsage);
991 if (res != OK) {
992 ALOGE("%s: Unable to configure usage %08x for stream %d",
993 __FUNCTION__, mUsage, mId);
994 return res;
995 }
996
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -0700997 res = native_window_set_scaling_mode(mConsumerInterface.get(),
998 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
999 if (res != OK) {
1000 ALOGE("%s: Unable to configure stream scaling: %s (%d)",
1001 __FUNCTION__, strerror(-res), res);
1002 return res;
1003 }
1004
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001005 res = setTransform(0);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001006 if (res != OK) {
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001007 return res;
1008 }
1009
Eino-Ville Talvalad4bcfde2012-06-07 17:12:38 -07001010 if (mFormat == HAL_PIXEL_FORMAT_BLOB) {
1011 res = native_window_set_buffers_geometry(mConsumerInterface.get(),
1012 mSize, 1, mFormat);
1013 if (res != OK) {
1014 ALOGE("%s: Unable to configure compressed stream buffer geometry"
1015 " %d x %d, size %d for stream %d",
1016 __FUNCTION__, mWidth, mHeight, mSize, mId);
1017 return res;
1018 }
1019 } else {
1020 res = native_window_set_buffers_geometry(mConsumerInterface.get(),
1021 mWidth, mHeight, mFormat);
1022 if (res != OK) {
1023 ALOGE("%s: Unable to configure stream buffer geometry"
1024 " %d x %d, format 0x%x for stream %d",
1025 __FUNCTION__, mWidth, mHeight, mFormat, mId);
1026 return res;
1027 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001028 }
1029
1030 int maxConsumerBuffers;
1031 res = mConsumerInterface->query(mConsumerInterface.get(),
1032 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &maxConsumerBuffers);
1033 if (res != OK) {
1034 ALOGE("%s: Unable to query consumer undequeued"
1035 " buffer count for stream %d", __FUNCTION__, mId);
1036 return res;
1037 }
1038 mMaxConsumerBuffers = maxConsumerBuffers;
1039
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001040 ALOGV("%s: Consumer wants %d buffers", __FUNCTION__,
1041 mMaxConsumerBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001042
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001043 mTotalBuffers = mMaxConsumerBuffers + mMaxProducerBuffers;
1044 mActiveBuffers = 0;
1045 mFrameCount = 0;
1046 mLastTimestamp = 0;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001047
1048 res = native_window_set_buffer_count(mConsumerInterface.get(),
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001049 mTotalBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001050 if (res != OK) {
1051 ALOGE("%s: Unable to set buffer count for stream %d",
1052 __FUNCTION__, mId);
1053 return res;
1054 }
1055
1056 // Register allocated buffers with HAL device
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001057 buffer_handle_t *buffers = new buffer_handle_t[mTotalBuffers];
1058 ANativeWindowBuffer **anwBuffers = new ANativeWindowBuffer*[mTotalBuffers];
1059 uint32_t bufferIdx = 0;
1060 for (; bufferIdx < mTotalBuffers; bufferIdx++) {
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001061 res = native_window_dequeue_buffer_and_wait(mConsumerInterface.get(),
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001062 &anwBuffers[bufferIdx]);
1063 if (res != OK) {
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001064 ALOGE("%s: Unable to dequeue buffer %d for initial registration for "
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001065 "stream %d", __FUNCTION__, bufferIdx, mId);
1066 goto cleanUpBuffers;
1067 }
1068
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001069 buffers[bufferIdx] = anwBuffers[bufferIdx]->handle;
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -07001070 ALOGV("%s: Buffer %p allocated", __FUNCTION__, (void*)buffers[bufferIdx]);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001071 }
1072
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001073 ALOGV("%s: Registering %d buffers with camera HAL", __FUNCTION__, mTotalBuffers);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001074 res = mDevice->ops->register_stream_buffers(mDevice,
1075 mId,
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001076 mTotalBuffers,
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001077 buffers);
1078 if (res != OK) {
1079 ALOGE("%s: Unable to register buffers with HAL device for stream %d",
1080 __FUNCTION__, mId);
1081 } else {
1082 mState = ACTIVE;
1083 }
1084
1085cleanUpBuffers:
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001086 ALOGV("%s: Cleaning up %d buffers", __FUNCTION__, bufferIdx);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001087 for (uint32_t i = 0; i < bufferIdx; i++) {
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001088 res = mConsumerInterface->cancelBuffer(mConsumerInterface.get(),
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001089 anwBuffers[i], -1);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001090 if (res != OK) {
1091 ALOGE("%s: Unable to cancel buffer %d after registration",
1092 __FUNCTION__, i);
1093 }
1094 }
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001095 delete[] anwBuffers;
1096 delete[] buffers;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001097
1098 return res;
1099}
1100
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001101status_t Camera2Device::StreamAdapter::release() {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -07001102 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001103 status_t res;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001104 ALOGV("%s: Releasing stream %d", __FUNCTION__, mId);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001105 if (mState >= ALLOCATED) {
1106 res = mDevice->ops->release_stream(mDevice, mId);
1107 if (res != OK) {
1108 ALOGE("%s: Unable to release stream %d",
1109 __FUNCTION__, mId);
1110 return res;
1111 }
1112 }
1113 if (mState >= CONNECTED) {
1114 res = native_window_api_disconnect(mConsumerInterface.get(),
1115 NATIVE_WINDOW_API_CAMERA);
1116 if (res != OK) {
1117 ALOGE("%s: Unable to disconnect stream %d from native window",
1118 __FUNCTION__, mId);
1119 return res;
1120 }
1121 }
1122 mId = -1;
Eino-Ville Talvala9cca4c62012-06-15 15:41:44 -07001123 mState = RELEASED;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001124 return OK;
1125}
1126
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001127status_t Camera2Device::StreamAdapter::setTransform(int transform) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -07001128 ATRACE_CALL();
Eino-Ville Talvalac94cd192012-06-15 12:47:42 -07001129 status_t res;
1130 if (mState < CONNECTED) {
1131 ALOGE("%s: Cannot set transform on unconnected stream", __FUNCTION__);
1132 return INVALID_OPERATION;
1133 }
1134 res = native_window_set_buffers_transform(mConsumerInterface.get(),
1135 transform);
1136 if (res != OK) {
1137 ALOGE("%s: Unable to configure stream transform to %x: %s (%d)",
1138 __FUNCTION__, transform, strerror(-res), res);
1139 }
1140 return res;
1141}
1142
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001143status_t Camera2Device::StreamAdapter::dump(int fd,
1144 const Vector<String16>& args) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -07001145 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001146 String8 result = String8::format(" Stream %d: %d x %d, format 0x%x\n",
1147 mId, mWidth, mHeight, mFormat);
1148 result.appendFormat(" size %d, usage 0x%x, requested format 0x%x\n",
1149 mSize, mUsage, mFormatRequested);
1150 result.appendFormat(" total buffers: %d, dequeued buffers: %d\n",
1151 mTotalBuffers, mActiveBuffers);
1152 result.appendFormat(" frame count: %d, last timestamp %lld\n",
1153 mFrameCount, mLastTimestamp);
1154 write(fd, result.string(), result.size());
1155 return OK;
1156}
1157
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001158const camera2_stream_ops *Camera2Device::StreamAdapter::getStreamOps() {
1159 return static_cast<camera2_stream_ops *>(this);
1160}
1161
1162ANativeWindow* Camera2Device::StreamAdapter::toANW(
1163 const camera2_stream_ops_t *w) {
1164 return static_cast<const StreamAdapter*>(w)->mConsumerInterface.get();
1165}
1166
1167int Camera2Device::StreamAdapter::dequeue_buffer(const camera2_stream_ops_t *w,
1168 buffer_handle_t** buffer) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -07001169 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001170 int res;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001171 StreamAdapter* stream =
1172 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
1173 if (stream->mState != ACTIVE) {
1174 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001175 return INVALID_OPERATION;
1176 }
1177
1178 ANativeWindow *a = toANW(w);
1179 ANativeWindowBuffer* anb;
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001180 res = native_window_dequeue_buffer_and_wait(a, &anb);
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001181 if (res != OK) {
1182 ALOGE("Stream %d dequeue: Error from native_window: %s (%d)", stream->mId,
1183 strerror(-res), res);
1184 return res;
1185 }
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001186
1187 *buffer = &(anb->handle);
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001188 stream->mActiveBuffers++;
1189
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001190 ALOGVV("Stream %d dequeue: Buffer %p dequeued", stream->mId, (void*)(**buffer));
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001191 return res;
1192}
1193
1194int Camera2Device::StreamAdapter::enqueue_buffer(const camera2_stream_ops_t* w,
1195 int64_t timestamp,
1196 buffer_handle_t* buffer) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -07001197 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001198 StreamAdapter *stream =
1199 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001200 stream->mFrameCount++;
1201 ALOGVV("Stream %d enqueue: Frame %d (%p) captured at %lld ns",
James Dong6638f3b2012-09-05 16:46:36 -07001202 stream->mId, stream->mFrameCount, (void*)(*buffer), timestamp);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001203 int state = stream->mState;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001204 if (state != ACTIVE) {
1205 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1206 return INVALID_OPERATION;
1207 }
1208 ANativeWindow *a = toANW(w);
1209 status_t err;
Eino-Ville Talvala228a5382012-08-13 12:16:06 -07001210
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001211 err = native_window_set_buffers_timestamp(a, timestamp);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001212 if (err != OK) {
1213 ALOGE("%s: Error setting timestamp on native window: %s (%d)",
1214 __FUNCTION__, strerror(-err), err);
1215 return err;
1216 }
1217 err = a->queueBuffer(a,
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001218 container_of(buffer, ANativeWindowBuffer, handle), -1);
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001219 if (err != OK) {
1220 ALOGE("%s: Error queueing buffer to native window: %s (%d)",
1221 __FUNCTION__, strerror(-err), err);
James Dong31d377b2012-08-09 17:43:46 -07001222 return err;
Eino-Ville Talvalabd4976a2012-06-07 10:40:25 -07001223 }
James Dong31d377b2012-08-09 17:43:46 -07001224
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001225 stream->mActiveBuffers--;
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001226 stream->mLastTimestamp = timestamp;
James Dong31d377b2012-08-09 17:43:46 -07001227 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001228}
1229
1230int Camera2Device::StreamAdapter::cancel_buffer(const camera2_stream_ops_t* w,
1231 buffer_handle_t* buffer) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -07001232 ATRACE_CALL();
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001233 StreamAdapter *stream =
1234 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
Eino-Ville Talvala750d74b2012-08-01 09:05:04 -07001235 ALOGVV("Stream %d cancel: Buffer %p",
1236 stream->mId, (void*)(*buffer));
Eino-Ville Talvala3297daa2012-06-14 10:49:45 -07001237 if (stream->mState != ACTIVE) {
1238 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001239 return INVALID_OPERATION;
1240 }
James Dong31d377b2012-08-09 17:43:46 -07001241
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001242 ANativeWindow *a = toANW(w);
James Dong31d377b2012-08-09 17:43:46 -07001243 int err = a->cancelBuffer(a,
Jamie Gennis1e5b2b32012-06-13 16:29:51 -07001244 container_of(buffer, ANativeWindowBuffer, handle), -1);
James Dong31d377b2012-08-09 17:43:46 -07001245 if (err != OK) {
1246 ALOGE("%s: Error canceling buffer to native window: %s (%d)",
1247 __FUNCTION__, strerror(-err), err);
1248 return err;
1249 }
1250
1251 stream->mActiveBuffers--;
1252 return OK;
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001253}
1254
1255int Camera2Device::StreamAdapter::set_crop(const camera2_stream_ops_t* w,
1256 int left, int top, int right, int bottom) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -07001257 ATRACE_CALL();
Eino-Ville Talvala6db981c2012-05-21 18:54:30 -07001258 int state = static_cast<const StreamAdapter*>(w)->mState;
1259 if (state != ACTIVE) {
1260 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1261 return INVALID_OPERATION;
1262 }
1263 ANativeWindow *a = toANW(w);
1264 android_native_rect_t crop = { left, top, right, bottom };
1265 return native_window_set_crop(a, &crop);
1266}
1267
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -07001268/**
1269 * Camera2Device::ReprocessStreamAdapter
1270 */
1271
1272#ifndef container_of
1273#define container_of(ptr, type, member) \
1274 (type *)((char*)(ptr) - offsetof(type, member))
1275#endif
1276
1277Camera2Device::ReprocessStreamAdapter::ReprocessStreamAdapter(camera2_device_t *d):
1278 mState(RELEASED),
1279 mDevice(d),
1280 mId(-1),
1281 mWidth(0), mHeight(0), mFormat(0),
1282 mActiveBuffers(0),
1283 mFrameCount(0)
1284{
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -07001285 ATRACE_CALL();
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -07001286 camera2_stream_in_ops::acquire_buffer = acquire_buffer;
1287 camera2_stream_in_ops::release_buffer = release_buffer;
1288}
1289
1290Camera2Device::ReprocessStreamAdapter::~ReprocessStreamAdapter() {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -07001291 ATRACE_CALL();
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -07001292 if (mState != RELEASED) {
1293 release();
1294 }
1295}
1296
1297status_t Camera2Device::ReprocessStreamAdapter::connectToDevice(
1298 const sp<StreamAdapter> &outputStream) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -07001299 ATRACE_CALL();
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -07001300 status_t res;
1301 ALOGV("%s: E", __FUNCTION__);
1302
1303 if (mState != RELEASED) return INVALID_OPERATION;
1304 if (outputStream == NULL) {
1305 ALOGE("%s: Null base stream passed to reprocess stream adapter",
1306 __FUNCTION__);
1307 return BAD_VALUE;
1308 }
1309
1310 mBaseStream = outputStream;
1311 mWidth = outputStream->getWidth();
1312 mHeight = outputStream->getHeight();
1313 mFormat = outputStream->getFormat();
1314
1315 ALOGV("%s: New reprocess stream parameters %d x %d, format 0x%x",
1316 __FUNCTION__, mWidth, mHeight, mFormat);
1317
1318 // Allocate device-side stream interface
1319
1320 uint32_t id;
1321 res = mDevice->ops->allocate_reprocess_stream_from_stream(mDevice,
1322 outputStream->getId(), getStreamOps(),
1323 &id);
1324 if (res != OK) {
1325 ALOGE("%s: Device reprocess stream allocation failed: %s (%d)",
1326 __FUNCTION__, strerror(-res), res);
1327 return res;
1328 }
1329
1330 ALOGV("%s: Allocated reprocess stream id %d based on stream %d",
1331 __FUNCTION__, id, outputStream->getId());
1332
1333 mId = id;
1334
1335 mState = ACTIVE;
1336
1337 return OK;
1338}
1339
1340status_t Camera2Device::ReprocessStreamAdapter::release() {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -07001341 ATRACE_CALL();
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -07001342 status_t res;
1343 ALOGV("%s: Releasing stream %d", __FUNCTION__, mId);
1344 if (mState >= ACTIVE) {
1345 res = mDevice->ops->release_reprocess_stream(mDevice, mId);
1346 if (res != OK) {
1347 ALOGE("%s: Unable to release stream %d",
1348 __FUNCTION__, mId);
1349 return res;
1350 }
1351 }
1352
1353 List<QueueEntry>::iterator s;
1354 for (s = mQueue.begin(); s != mQueue.end(); s++) {
1355 sp<BufferReleasedListener> listener = s->releaseListener.promote();
1356 if (listener != 0) listener->onBufferReleased(s->handle);
1357 }
1358 for (s = mInFlightQueue.begin(); s != mInFlightQueue.end(); s++) {
1359 sp<BufferReleasedListener> listener = s->releaseListener.promote();
1360 if (listener != 0) listener->onBufferReleased(s->handle);
1361 }
1362 mQueue.clear();
1363 mInFlightQueue.clear();
1364
1365 mState = RELEASED;
1366 return OK;
1367}
1368
1369status_t Camera2Device::ReprocessStreamAdapter::pushIntoStream(
1370 buffer_handle_t *handle, const wp<BufferReleasedListener> &releaseListener) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -07001371 ATRACE_CALL();
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -07001372 // TODO: Some error checking here would be nice
1373 ALOGV("%s: Pushing buffer %p to stream", __FUNCTION__, (void*)(*handle));
1374
1375 QueueEntry entry;
1376 entry.handle = handle;
1377 entry.releaseListener = releaseListener;
1378 mQueue.push_back(entry);
1379 return OK;
1380}
1381
1382status_t Camera2Device::ReprocessStreamAdapter::dump(int fd,
1383 const Vector<String16>& args) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -07001384 ATRACE_CALL();
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -07001385 String8 result =
1386 String8::format(" Reprocess stream %d: %d x %d, fmt 0x%x\n",
1387 mId, mWidth, mHeight, mFormat);
1388 result.appendFormat(" acquired buffers: %d\n",
1389 mActiveBuffers);
1390 result.appendFormat(" frame count: %d\n",
1391 mFrameCount);
1392 write(fd, result.string(), result.size());
1393 return OK;
1394}
1395
1396const camera2_stream_in_ops *Camera2Device::ReprocessStreamAdapter::getStreamOps() {
1397 return static_cast<camera2_stream_in_ops *>(this);
1398}
1399
1400int Camera2Device::ReprocessStreamAdapter::acquire_buffer(
1401 const camera2_stream_in_ops_t *w,
1402 buffer_handle_t** buffer) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -07001403 ATRACE_CALL();
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -07001404 int res;
1405 ReprocessStreamAdapter* stream =
1406 const_cast<ReprocessStreamAdapter*>(
1407 static_cast<const ReprocessStreamAdapter*>(w));
1408 if (stream->mState != ACTIVE) {
1409 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
1410 return INVALID_OPERATION;
1411 }
1412
1413 if (stream->mQueue.empty()) {
1414 *buffer = NULL;
1415 return OK;
1416 }
1417
1418 QueueEntry &entry = *(stream->mQueue.begin());
1419
1420 *buffer = entry.handle;
1421
1422 stream->mInFlightQueue.push_back(entry);
1423 stream->mQueue.erase(stream->mQueue.begin());
1424
1425 stream->mActiveBuffers++;
1426
1427 ALOGV("Stream %d acquire: Buffer %p acquired", stream->mId,
1428 (void*)(**buffer));
1429 return OK;
1430}
1431
1432int Camera2Device::ReprocessStreamAdapter::release_buffer(
1433 const camera2_stream_in_ops_t* w,
1434 buffer_handle_t* buffer) {
Eino-Ville Talvala4bb81182012-09-24 09:46:53 -07001435 ATRACE_CALL();
Eino-Ville Talvalada6665c2012-08-29 17:37:16 -07001436 ReprocessStreamAdapter *stream =
1437 const_cast<ReprocessStreamAdapter*>(
1438 static_cast<const ReprocessStreamAdapter*>(w) );
1439 stream->mFrameCount++;
1440 ALOGV("Reprocess stream %d release: Frame %d (%p)",
1441 stream->mId, stream->mFrameCount, (void*)*buffer);
1442 int state = stream->mState;
1443 if (state != ACTIVE) {
1444 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1445 return INVALID_OPERATION;
1446 }
1447 stream->mActiveBuffers--;
1448
1449 List<QueueEntry>::iterator s;
1450 for (s = stream->mInFlightQueue.begin(); s != stream->mInFlightQueue.end(); s++) {
1451 if ( s->handle == buffer ) break;
1452 }
1453 if (s == stream->mInFlightQueue.end()) {
1454 ALOGE("%s: Can't find buffer %p in in-flight list!", __FUNCTION__,
1455 buffer);
1456 return INVALID_OPERATION;
1457 }
1458
1459 sp<BufferReleasedListener> listener = s->releaseListener.promote();
1460 if (listener != 0) {
1461 listener->onBufferReleased(s->handle);
1462 } else {
1463 ALOGE("%s: Can't free buffer - missing listener", __FUNCTION__);
1464 }
1465 stream->mInFlightQueue.erase(s);
1466
1467 return OK;
1468}
Eino-Ville Talvala61ab9f92012-05-17 10:30:54 -07001469
1470}; // namespace android