blob: 0f9e3784b7371cbe454b4bc7bb9b20daf2f76124 [file] [log] [blame]
Ari Hausman-Cohen73442152016-06-08 15:50:49 -07001/*
2 * Copyright (C) 2016 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
17// Modified from hardware/libhardware/modules/camera/Camera.cpp
18
19#include <cstdlib>
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -070020#include <memory>
21#include <vector>
Ari Hausman-Cohen73442152016-06-08 15:50:49 -070022#include <stdio.h>
23#include <hardware/camera3.h>
24#include <sync/sync.h>
25#include <system/camera_metadata.h>
26#include <system/graphics.h>
27#include <utils/Mutex.h>
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -070028
29#include "metadata/metadata_common.h"
Ari Hausman-Cohen73442152016-06-08 15:50:49 -070030
31//#define LOG_NDEBUG 0
32#define LOG_TAG "Camera"
33#include <cutils/log.h>
34
35#define ATRACE_TAG (ATRACE_TAG_CAMERA | ATRACE_TAG_HAL)
36#include <utils/Trace.h>
37
Ari Hausman-Cohen3841a7f2016-07-19 17:27:52 -070038#include "camera.h"
Ari Hausman-Cohen73442152016-06-08 15:50:49 -070039
40#define CAMERA_SYNC_TIMEOUT 5000 // in msecs
41
42namespace default_camera_hal {
43
44extern "C" {
45// Shim passed to the framework to close an opened device.
46static int close_device(hw_device_t* dev)
47{
48 camera3_device_t* cam_dev = reinterpret_cast<camera3_device_t*>(dev);
49 Camera* cam = static_cast<Camera*>(cam_dev->priv);
50 return cam->close();
51}
52} // extern "C"
53
54Camera::Camera(int id)
55 : mId(id),
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -070056 mSettingsSet(false),
Ari Hausman-Cohen73442152016-06-08 15:50:49 -070057 mBusy(false),
58 mCallbackOps(NULL),
Ari Hausman-Cohen0b2113c2016-10-03 13:43:13 -070059 mInFlightTracker(new RequestTracker)
Ari Hausman-Cohen73442152016-06-08 15:50:49 -070060{
61 memset(&mTemplates, 0, sizeof(mTemplates));
62 memset(&mDevice, 0, sizeof(mDevice));
63 mDevice.common.tag = HARDWARE_DEVICE_TAG;
Ari Hausman-Cohen900c1e32016-06-20 16:52:41 -070064 mDevice.common.version = CAMERA_DEVICE_API_VERSION_3_4;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -070065 mDevice.common.close = close_device;
66 mDevice.ops = const_cast<camera3_device_ops_t*>(&sOps);
67 mDevice.priv = this;
68}
69
70Camera::~Camera()
71{
Ari Hausman-Cohen73442152016-06-08 15:50:49 -070072}
73
Ari Hausman-Cohen345bd3a2016-06-13 15:33:53 -070074int Camera::openDevice(const hw_module_t *module, hw_device_t **device)
Ari Hausman-Cohen73442152016-06-08 15:50:49 -070075{
76 ALOGI("%s:%d: Opening camera device", __func__, mId);
77 ATRACE_CALL();
78 android::Mutex::Autolock al(mDeviceLock);
79
80 if (mBusy) {
81 ALOGE("%s:%d: Error! Camera device already opened", __func__, mId);
82 return -EBUSY;
83 }
84
Ari Hausman-Cohen345bd3a2016-06-13 15:33:53 -070085 int connectResult = connect();
86 if (connectResult != 0) {
87 return connectResult;
88 }
Ari Hausman-Cohen73442152016-06-08 15:50:49 -070089 mBusy = true;
90 mDevice.common.module = const_cast<hw_module_t*>(module);
91 *device = &mDevice.common;
92 return 0;
93}
94
95int Camera::getInfo(struct camera_info *info)
96{
Ari Hausman-Cohen73442152016-06-08 15:50:49 -070097 info->device_version = mDevice.common.version;
98 initDeviceInfo(info);
Ari Hausman-Cohene31e1f32016-11-16 15:02:07 -080099 if (!mStaticInfo) {
100 int res = loadStaticInfo();
101 if (res) {
102 return res;
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700103 }
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700104 }
Ari Hausman-Cohene31e1f32016-11-16 15:02:07 -0800105 info->static_camera_characteristics = mStaticInfo->raw_metadata();
106 info->facing = mStaticInfo->facing();
107 info->orientation = mStaticInfo->orientation();
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700108
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700109 return 0;
110}
111
Ari Hausman-Cohene31e1f32016-11-16 15:02:07 -0800112int Camera::loadStaticInfo() {
113 // Using a lock here ensures |mStaticInfo| will only ever be set once,
114 // even in concurrent situations.
115 android::Mutex::Autolock al(mStaticInfoLock);
116
117 if (mStaticInfo) {
118 return 0;
119 }
120
121 std::unique_ptr<android::CameraMetadata> static_metadata =
122 std::make_unique<android::CameraMetadata>();
123 int res = initStaticInfo(static_metadata.get());
124 if (res) {
125 ALOGE("%s:%d: Failed to get static info from device.",
126 __func__, mId);
127 return res;
128 }
129
130 mStaticInfo.reset(StaticProperties::NewStaticProperties(
131 std::move(static_metadata)));
132 if (!mStaticInfo) {
133 ALOGE("%s:%d: Failed to initialize static properties from device metadata.",
134 __func__, mId);
135 return -ENODEV;
136 }
137
138 return 0;
139}
140
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700141int Camera::close()
142{
143 ALOGI("%s:%d: Closing camera device", __func__, mId);
144 ATRACE_CALL();
145 android::Mutex::Autolock al(mDeviceLock);
146
147 if (!mBusy) {
148 ALOGE("%s:%d: Error! Camera device not open", __func__, mId);
149 return -EINVAL;
150 }
151
Ari Hausman-Cohenc5a48522016-11-16 10:53:52 -0800152 flush();
Ari Hausman-Cohen5acb4002016-11-29 18:35:17 -0800153 disconnect();
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700154 mBusy = false;
155 return 0;
156}
157
158int Camera::initialize(const camera3_callback_ops_t *callback_ops)
159{
160 int res;
161
162 ALOGV("%s:%d: callback_ops=%p", __func__, mId, callback_ops);
163 mCallbackOps = callback_ops;
164 // per-device specific initialization
165 res = initDevice();
166 if (res != 0) {
167 ALOGE("%s:%d: Failed to initialize device!", __func__, mId);
168 return res;
169 }
170 return 0;
171}
172
173int Camera::configureStreams(camera3_stream_configuration_t *stream_config)
174{
Ari Hausman-Cohenef523102016-11-21 17:02:01 -0800175 android::Mutex::Autolock al(mDeviceLock);
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700176
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700177 ALOGV("%s:%d: stream_config=%p", __func__, mId, stream_config);
178 ATRACE_CALL();
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700179
Ari Hausman-Cohenef523102016-11-21 17:02:01 -0800180 // Check that there are no in-flight requests.
181 if (!mInFlightTracker->Empty()) {
182 ALOGE("%s:%d: Can't configure streams while frames are in flight.",
183 __func__, mId);
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700184 return -EINVAL;
185 }
186
Ari Hausman-Cohenef523102016-11-21 17:02:01 -0800187 // Verify the set of streams in aggregate, and perform configuration if valid.
188 int res = validateStreamConfiguration(stream_config);
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700189 if (res) {
Ari Hausman-Cohenef523102016-11-21 17:02:01 -0800190 ALOGE("%s:%d: Failed to validate stream set", __func__, mId);
191 } else {
192 // Set up all streams. Since they've been validated,
193 // this should only result in fatal (-ENODEV) errors.
194 // This occurs after validation to ensure that if there
195 // is a non-fatal error, the stream configuration doesn't change states.
196 res = setupStreams(stream_config);
197 if (res) {
198 ALOGE("%s:%d: Failed to setup stream set", __func__, mId);
199 }
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700200 }
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700201
Ari Hausman-Cohenef523102016-11-21 17:02:01 -0800202 // Set trackers based on result.
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700203 if (!res) {
Ari Hausman-Cohenef523102016-11-21 17:02:01 -0800204 // Success, set up the in-flight trackers for the new streams.
205 mInFlightTracker->SetStreamConfiguration(*stream_config);
206 // Must provide new settings for the new configuration.
207 mSettingsSet = false;
Ari Hausman-Cohen0b2113c2016-10-03 13:43:13 -0700208 } else if (res != -EINVAL) {
Ari Hausman-Cohenef523102016-11-21 17:02:01 -0800209 // Fatal error, the old configuration is invalid.
Ari Hausman-Cohen0b2113c2016-10-03 13:43:13 -0700210 mInFlightTracker->ClearStreamConfiguration();
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700211 }
Ari Hausman-Cohenef523102016-11-21 17:02:01 -0800212 // On a non-fatal error the old configuration, if any, remains valid.
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700213 return res;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700214}
215
Ari Hausman-Cohenef523102016-11-21 17:02:01 -0800216int Camera::validateStreamConfiguration(
217 const camera3_stream_configuration_t* stream_config)
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700218{
Ari Hausman-Cohenef523102016-11-21 17:02:01 -0800219 // Check that the configuration is well-formed.
220 if (stream_config == nullptr) {
221 ALOGE("%s:%d: NULL stream configuration array", __func__, mId);
222 return -EINVAL;
223 } else if (stream_config->num_streams == 0) {
224 ALOGE("%s:%d: Empty stream configuration array", __func__, mId);
225 return -EINVAL;
226 } else if (stream_config->streams == nullptr) {
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700227 ALOGE("%s:%d: NULL stream configuration streams", __func__, mId);
Ari Hausman-Cohenef523102016-11-21 17:02:01 -0800228 return -EINVAL;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700229 }
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700230
Ari Hausman-Cohenef523102016-11-21 17:02:01 -0800231 // Check that the configuration is supported.
232 // Make sure static info has been initialized before trying to use it.
233 if (!mStaticInfo) {
234 int res = loadStaticInfo();
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700235 if (res) {
Ari Hausman-Cohenef523102016-11-21 17:02:01 -0800236 return res;
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700237 }
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700238 }
Ari Hausman-Cohenef523102016-11-21 17:02:01 -0800239 if (!mStaticInfo->StreamConfigurationSupported(stream_config)) {
240 ALOGE("%s:%d: Stream configuration does not match static "
241 "metadata restrictions.", __func__, mId);
242 return -EINVAL;
243 }
244
245 // Dataspace support is poorly documented - unclear if the expectation
246 // is that a device supports ALL dataspaces that could match a given
247 // format. For now, defer to child class implementation.
248 // Rotation support isn't described by metadata, so must defer to device.
249 if (!validateDataspacesAndRotations(stream_config)) {
250 ALOGE("%s:%d: Device can not handle configuration "
251 "dataspaces or rotations.", __func__, mId);
252 return -EINVAL;
253 }
254
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700255 return 0;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700256}
257
258bool Camera::isValidTemplateType(int type)
259{
Ari Hausman-Cohen900c1e32016-06-20 16:52:41 -0700260 return type > 0 && type < CAMERA3_TEMPLATE_COUNT;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700261}
262
263const camera_metadata_t* Camera::constructDefaultRequestSettings(int type)
264{
265 ALOGV("%s:%d: type=%d", __func__, mId, type);
266
267 if (!isValidTemplateType(type)) {
268 ALOGE("%s:%d: Invalid template request type: %d", __func__, mId, type);
269 return NULL;
270 }
Ari Hausman-Cohen49925842016-06-21 14:07:58 -0700271
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700272 if (!mTemplates[type]) {
Ari Hausman-Cohene31e1f32016-11-16 15:02:07 -0800273 // Check if the device has the necessary features
274 // for the requested template. If not, don't bother.
275 if (!mStaticInfo->TemplateSupported(type)) {
276 ALOGW("%s:%d: Camera does not support template type %d",
277 __func__, mId, type);
278 return NULL;
279 }
280
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700281 // Initialize this template if it hasn't been initialized yet.
282 std::unique_ptr<android::CameraMetadata> new_template =
283 std::make_unique<android::CameraMetadata>();
284 int res = initTemplate(type, new_template.get());
285 if (res || !new_template) {
286 ALOGE("%s:%d: Failed to generate template of type: %d",
287 __func__, mId, type);
288 return NULL;
289 }
290 mTemplates[type] = std::move(new_template);
291 }
292
293 // The "locking" here only causes non-const methods to fail,
294 // which is not a problem since the CameraMetadata being locked
295 // is already const. Destructing automatically "unlocks".
296 return mTemplates[type]->getAndLock();
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700297}
298
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700299int Camera::processCaptureRequest(camera3_capture_request_t *temp_request)
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700300{
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700301 int res;
Ari Hausman-Cohenc5a48522016-11-16 10:53:52 -0800302 // TODO(b/32917568): A capture request submitted or ongoing during a flush
303 // should be returned with an error; for now they are mutually exclusive.
304 android::Mutex::Autolock al(mFlushLock);
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700305
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700306 ATRACE_CALL();
307
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700308 if (temp_request == NULL) {
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700309 ALOGE("%s:%d: NULL request recieved", __func__, mId);
310 return -EINVAL;
311 }
312
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700313 // Make a persistent copy of request, since otherwise it won't live
314 // past the end of this method.
315 std::shared_ptr<CaptureRequest> request = std::make_shared<CaptureRequest>(temp_request);
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700316
Ari Hausman-Cohenad6fe2b2016-11-16 10:48:07 -0800317 ALOGV("%s:%d: frame: %d", __func__, mId, request->frame_number);
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700318
Ari Hausman-Cohenef523102016-11-21 17:02:01 -0800319 if (!mInFlightTracker->CanAddRequest(*request)) {
320 // Streams are full or frame number is not unique.
321 ALOGE("%s:%d: Can not add request.", __func__, mId);
322 return -EINVAL;
323 }
324
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700325 // Null/Empty indicates use last settings
326 if (request->settings.isEmpty() && !mSettingsSet) {
327 ALOGE("%s:%d: NULL settings without previous set Frame:%d",
328 __func__, mId, request->frame_number);
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700329 return -EINVAL;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700330 }
331
332 if (request->input_buffer != NULL) {
333 ALOGV("%s:%d: Reprocessing input buffer %p", __func__, mId,
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700334 request->input_buffer.get());
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700335 } else {
336 ALOGV("%s:%d: Capturing new frame.", __func__, mId);
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700337 }
338
Ari Hausman-Cohenef523102016-11-21 17:02:01 -0800339 if (!isValidRequestSettings(request->settings)) {
340 ALOGE("%s:%d: Invalid request settings.", __func__, mId);
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700341 return -EINVAL;
342 }
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700343
344 // Pre-process output buffers.
345 if (request->output_buffers.size() <= 0) {
346 ALOGE("%s:%d: Invalid number of output buffers: %d", __func__, mId,
347 request->output_buffers.size());
348 return -EINVAL;
349 }
350 for (auto& output_buffer : request->output_buffers) {
351 res = preprocessCaptureBuffer(&output_buffer);
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700352 if (res)
353 return -ENODEV;
354 }
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700355
Ari Hausman-Cohen0b2113c2016-10-03 13:43:13 -0700356 // Add the request to tracking.
357 if (!mInFlightTracker->Add(request)) {
358 ALOGE("%s:%d: Failed to track request for frame %d.",
359 __func__, mId, request->frame_number);
360 return -ENODEV;
361 }
362
Ari Hausman-Cohenef523102016-11-21 17:02:01 -0800363 // Valid settings have been provided (mSettingsSet is a misnomer;
364 // all that matters is that a previous request with valid settings
365 // has been passed to the device, not that they've been set).
366 mSettingsSet = true;
367
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700368 // Send the request off to the device for completion.
369 enqueueRequest(request);
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700370
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700371 // Request is now in flight. The device will call completeRequest
372 // asynchronously when it is done filling buffers and metadata.
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700373 return 0;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700374}
375
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700376void Camera::completeRequest(std::shared_ptr<CaptureRequest> request, int err)
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700377{
Ari Hausman-Cohen0b2113c2016-10-03 13:43:13 -0700378 if (!mInFlightTracker->Remove(request)) {
Ari Hausman-Cohenc5a48522016-11-16 10:53:52 -0800379 ALOGE("%s:%d: Completed request %p is not being tracked. "
380 "It may have been cleared out during a flush.",
Ari Hausman-Cohen0b2113c2016-10-03 13:43:13 -0700381 __func__, mId, request.get());
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700382 return;
383 }
384
Ari Hausman-Cohen0b2113c2016-10-03 13:43:13 -0700385 // Since |request| has been removed from the tracking, this method
386 // MUST call sendResult (can still return a result in an error state, e.g.
387 // through completeRequestWithError) so the frame doesn't get lost.
388
389 if (err) {
390 ALOGE("%s:%d: Error completing request for frame %d.",
391 __func__, mId, request->frame_number);
392 completeRequestWithError(request);
393 return;
394 }
395
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700396 // Notify the framework with the shutter time (extracted from the result).
397 int64_t timestamp = 0;
398 // TODO(b/31360070): The general metadata methods should be part of the
399 // default_camera_hal namespace, not the v4l2_camera_hal namespace.
400 int res = v4l2_camera_hal::SingleTagValue(
401 request->settings, ANDROID_SENSOR_TIMESTAMP, &timestamp);
402 if (res) {
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700403 ALOGE("%s:%d: Request for frame %d is missing required metadata.",
404 __func__, mId, request->frame_number);
Ari Hausman-Cohenfb161112016-09-29 14:35:00 -0700405 // TODO(b/31653322): Send RESULT error.
406 // For now sending REQUEST error instead.
407 completeRequestWithError(request);
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700408 return;
409 }
410 notifyShutter(request->frame_number, timestamp);
411
412 // TODO(b/31653322): Check all returned buffers for errors
413 // (if any, send BUFFER error).
414
Ari Hausman-Cohenfb161112016-09-29 14:35:00 -0700415 sendResult(request);
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700416}
417
Ari Hausman-Cohenc5a48522016-11-16 10:53:52 -0800418int Camera::flush()
419{
420 ALOGV("%s:%d: Flushing.", __func__, mId);
421 // TODO(b/32917568): Synchronization. Behave "appropriately"
422 // (i.e. according to camera3.h) if process_capture_request()
423 // is called concurrently with this (in either order).
424 // Since the callback to completeRequest also may happen on a separate
425 // thread, this function should behave nicely concurrently with that too.
426 android::Mutex::Autolock al(mFlushLock);
427
428 std::set<std::shared_ptr<CaptureRequest>> requests;
429 mInFlightTracker->Clear(&requests);
430 for (auto& request : requests) {
431 // TODO(b/31653322): See camera3.h. Should return different error
432 // depending on status of the request.
433 completeRequestWithError(request);
434 }
435
436 ALOGV("%s:%d: Flushed %u requests.", __func__, mId, requests.size());
437
438 // Call down into the device flushing.
439 return flushBuffers();
440}
441
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700442int Camera::preprocessCaptureBuffer(camera3_stream_buffer_t *buffer)
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700443{
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700444 int res;
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700445 // TODO(b/29334616): This probably should be non-blocking; part
446 // of the asynchronous request processing.
447 if (buffer->acquire_fence != -1) {
448 res = sync_wait(buffer->acquire_fence, CAMERA_SYNC_TIMEOUT);
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700449 if (res == -ETIME) {
450 ALOGE("%s:%d: Timeout waiting on buffer acquire fence",
451 __func__, mId);
452 return res;
453 } else if (res) {
454 ALOGE("%s:%d: Error waiting on buffer acquire fence: %s(%d)",
455 __func__, mId, strerror(-res), res);
456 return res;
457 }
Eric Jeongeadafff2017-08-01 19:40:03 +0900458 ::close(buffer->acquire_fence);
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700459 }
460
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700461 // Acquire fence has been waited upon.
462 buffer->acquire_fence = -1;
463 // No release fence waiting unless the device sets it.
464 buffer->release_fence = -1;
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700465
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700466 buffer->status = CAMERA3_BUFFER_STATUS_OK;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700467 return 0;
468}
469
470void Camera::notifyShutter(uint32_t frame_number, uint64_t timestamp)
471{
Ari Hausman-Cohenfb161112016-09-29 14:35:00 -0700472 camera3_notify_msg_t message;
473 memset(&message, 0, sizeof(message));
474 message.type = CAMERA3_MSG_SHUTTER;
475 message.message.shutter.frame_number = frame_number;
476 message.message.shutter.timestamp = timestamp;
477 mCallbackOps->notify(mCallbackOps, &message);
478}
479
480void Camera::completeRequestWithError(std::shared_ptr<CaptureRequest> request)
481{
482 // Send an error notification.
483 camera3_notify_msg_t message;
484 memset(&message, 0, sizeof(message));
485 message.type = CAMERA3_MSG_ERROR;
486 message.message.error.frame_number = request->frame_number;
487 message.message.error.error_stream = nullptr;
488 message.message.error.error_code = CAMERA3_MSG_ERROR_REQUEST;
489 mCallbackOps->notify(mCallbackOps, &message);
490
491 // TODO(b/31856611): Ensure all the buffers indicate their error status.
492
493 // Send the errored out result.
494 sendResult(request);
495}
496
497void Camera::sendResult(std::shared_ptr<CaptureRequest> request) {
498 // Fill in the result struct
499 // (it only needs to live until the end of the framework callback).
500 camera3_capture_result_t result {
501 request->frame_number,
502 request->settings.getAndLock(),
503 request->output_buffers.size(),
504 request->output_buffers.data(),
505 request->input_buffer.get(),
506 1 // Total result; only 1 part.
507 };
508 // Make the framework callback.
509 mCallbackOps->process_capture_result(mCallbackOps, &result);
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700510}
511
512void Camera::dump(int fd)
513{
514 ALOGV("%s:%d: Dumping to fd %d", __func__, mId, fd);
515 ATRACE_CALL();
516 android::Mutex::Autolock al(mDeviceLock);
517
518 dprintf(fd, "Camera ID: %d (Busy: %d)\n", mId, mBusy);
519
520 // TODO: dump all settings
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700521}
522
523const char* Camera::templateToString(int type)
524{
525 switch (type) {
526 case CAMERA3_TEMPLATE_PREVIEW:
527 return "CAMERA3_TEMPLATE_PREVIEW";
528 case CAMERA3_TEMPLATE_STILL_CAPTURE:
529 return "CAMERA3_TEMPLATE_STILL_CAPTURE";
530 case CAMERA3_TEMPLATE_VIDEO_RECORD:
531 return "CAMERA3_TEMPLATE_VIDEO_RECORD";
532 case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT:
533 return "CAMERA3_TEMPLATE_VIDEO_SNAPSHOT";
534 case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
535 return "CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG";
536 }
537 // TODO: support vendor templates
538 return "Invalid template type!";
539}
540
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700541extern "C" {
542// Get handle to camera from device priv data
543static Camera *camdev_to_camera(const camera3_device_t *dev)
544{
545 return reinterpret_cast<Camera*>(dev->priv);
546}
547
548static int initialize(const camera3_device_t *dev,
549 const camera3_callback_ops_t *callback_ops)
550{
551 return camdev_to_camera(dev)->initialize(callback_ops);
552}
553
554static int configure_streams(const camera3_device_t *dev,
555 camera3_stream_configuration_t *stream_list)
556{
557 return camdev_to_camera(dev)->configureStreams(stream_list);
558}
559
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700560static const camera_metadata_t *construct_default_request_settings(
561 const camera3_device_t *dev, int type)
562{
563 return camdev_to_camera(dev)->constructDefaultRequestSettings(type);
564}
565
566static int process_capture_request(const camera3_device_t *dev,
567 camera3_capture_request_t *request)
568{
569 return camdev_to_camera(dev)->processCaptureRequest(request);
570}
571
572static void dump(const camera3_device_t *dev, int fd)
573{
574 camdev_to_camera(dev)->dump(fd);
575}
576
Ari Hausman-Cohenc5a48522016-11-16 10:53:52 -0800577static int flush(const camera3_device_t *dev)
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700578{
Ari Hausman-Cohenc5a48522016-11-16 10:53:52 -0800579 return camdev_to_camera(dev)->flush();
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700580}
581
582} // extern "C"
583
584const camera3_device_ops_t Camera::sOps = {
585 .initialize = default_camera_hal::initialize,
586 .configure_streams = default_camera_hal::configure_streams,
Ari Hausman-Cohen900c1e32016-06-20 16:52:41 -0700587 .register_stream_buffers = nullptr,
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700588 .construct_default_request_settings
589 = default_camera_hal::construct_default_request_settings,
590 .process_capture_request = default_camera_hal::process_capture_request,
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700591 .get_metadata_vendor_tag_ops = nullptr,
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700592 .dump = default_camera_hal::dump,
593 .flush = default_camera_hal::flush,
594 .reserved = {0},
595};
596
Ari Hausman-Cohen3841a7f2016-07-19 17:27:52 -0700597} // namespace default_camera_hal