blob: 5a89e3e1055be266fcab86feb4407fb79210fb60 [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-Cohen3841a7f2016-07-19 17:27:52 -070030#include "stream.h"
Ari Hausman-Cohen73442152016-06-08 15:50:49 -070031
32//#define LOG_NDEBUG 0
33#define LOG_TAG "Camera"
34#include <cutils/log.h>
35
36#define ATRACE_TAG (ATRACE_TAG_CAMERA | ATRACE_TAG_HAL)
37#include <utils/Trace.h>
38
Ari Hausman-Cohen3841a7f2016-07-19 17:27:52 -070039#include "camera.h"
Ari Hausman-Cohen73442152016-06-08 15:50:49 -070040
41#define CAMERA_SYNC_TIMEOUT 5000 // in msecs
42
43namespace default_camera_hal {
44
45extern "C" {
46// Shim passed to the framework to close an opened device.
47static int close_device(hw_device_t* dev)
48{
49 camera3_device_t* cam_dev = reinterpret_cast<camera3_device_t*>(dev);
50 Camera* cam = static_cast<Camera*>(cam_dev->priv);
51 return cam->close();
52}
53} // extern "C"
54
55Camera::Camera(int id)
56 : mId(id),
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -070057 mSettingsSet(false),
Ari Hausman-Cohen73442152016-06-08 15:50:49 -070058 mBusy(false),
59 mCallbackOps(NULL),
60 mStreams(NULL),
Ari Hausman-Cohen0b2113c2016-10-03 13:43:13 -070061 mNumStreams(0),
62 mInFlightTracker(new RequestTracker)
Ari Hausman-Cohen73442152016-06-08 15:50:49 -070063{
64 memset(&mTemplates, 0, sizeof(mTemplates));
65 memset(&mDevice, 0, sizeof(mDevice));
66 mDevice.common.tag = HARDWARE_DEVICE_TAG;
Ari Hausman-Cohen900c1e32016-06-20 16:52:41 -070067 mDevice.common.version = CAMERA_DEVICE_API_VERSION_3_4;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -070068 mDevice.common.close = close_device;
69 mDevice.ops = const_cast<camera3_device_ops_t*>(&sOps);
70 mDevice.priv = this;
71}
72
73Camera::~Camera()
74{
Ari Hausman-Cohen73442152016-06-08 15:50:49 -070075}
76
Ari Hausman-Cohen345bd3a2016-06-13 15:33:53 -070077int Camera::openDevice(const hw_module_t *module, hw_device_t **device)
Ari Hausman-Cohen73442152016-06-08 15:50:49 -070078{
79 ALOGI("%s:%d: Opening camera device", __func__, mId);
80 ATRACE_CALL();
81 android::Mutex::Autolock al(mDeviceLock);
82
83 if (mBusy) {
84 ALOGE("%s:%d: Error! Camera device already opened", __func__, mId);
85 return -EBUSY;
86 }
87
Ari Hausman-Cohen345bd3a2016-06-13 15:33:53 -070088 int connectResult = connect();
89 if (connectResult != 0) {
90 return connectResult;
91 }
Ari Hausman-Cohen73442152016-06-08 15:50:49 -070092 mBusy = true;
93 mDevice.common.module = const_cast<hw_module_t*>(module);
94 *device = &mDevice.common;
95 return 0;
96}
97
98int Camera::getInfo(struct camera_info *info)
99{
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700100 info->device_version = mDevice.common.version;
101 initDeviceInfo(info);
Ari Hausman-Cohene31e1f32016-11-16 15:02:07 -0800102 if (!mStaticInfo) {
103 int res = loadStaticInfo();
104 if (res) {
105 return res;
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700106 }
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700107 }
Ari Hausman-Cohene31e1f32016-11-16 15:02:07 -0800108 info->static_camera_characteristics = mStaticInfo->raw_metadata();
109 info->facing = mStaticInfo->facing();
110 info->orientation = mStaticInfo->orientation();
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700111
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700112 return 0;
113}
114
Ari Hausman-Cohene31e1f32016-11-16 15:02:07 -0800115int Camera::loadStaticInfo() {
116 // Using a lock here ensures |mStaticInfo| will only ever be set once,
117 // even in concurrent situations.
118 android::Mutex::Autolock al(mStaticInfoLock);
119
120 if (mStaticInfo) {
121 return 0;
122 }
123
124 std::unique_ptr<android::CameraMetadata> static_metadata =
125 std::make_unique<android::CameraMetadata>();
126 int res = initStaticInfo(static_metadata.get());
127 if (res) {
128 ALOGE("%s:%d: Failed to get static info from device.",
129 __func__, mId);
130 return res;
131 }
132
133 mStaticInfo.reset(StaticProperties::NewStaticProperties(
134 std::move(static_metadata)));
135 if (!mStaticInfo) {
136 ALOGE("%s:%d: Failed to initialize static properties from device metadata.",
137 __func__, mId);
138 return -ENODEV;
139 }
140
141 return 0;
142}
143
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700144int Camera::close()
145{
146 ALOGI("%s:%d: Closing camera device", __func__, mId);
147 ATRACE_CALL();
148 android::Mutex::Autolock al(mDeviceLock);
149
150 if (!mBusy) {
151 ALOGE("%s:%d: Error! Camera device not open", __func__, mId);
152 return -EINVAL;
153 }
154
Ari Hausman-Cohen345bd3a2016-06-13 15:33:53 -0700155 disconnect();
Ari Hausman-Cohenc5a48522016-11-16 10:53:52 -0800156 flush();
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700157 mBusy = false;
158 return 0;
159}
160
161int Camera::initialize(const camera3_callback_ops_t *callback_ops)
162{
163 int res;
164
165 ALOGV("%s:%d: callback_ops=%p", __func__, mId, callback_ops);
166 mCallbackOps = callback_ops;
167 // per-device specific initialization
168 res = initDevice();
169 if (res != 0) {
170 ALOGE("%s:%d: Failed to initialize device!", __func__, mId);
171 return res;
172 }
173 return 0;
174}
175
176int Camera::configureStreams(camera3_stream_configuration_t *stream_config)
177{
178 camera3_stream_t *astream;
179 Stream **newStreams = NULL;
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700180 int res = 0;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700181
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700182 // Must provide new settings after configureStreams.
183 mSettingsSet = false;
184
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700185 ALOGV("%s:%d: stream_config=%p", __func__, mId, stream_config);
186 ATRACE_CALL();
187 android::Mutex::Autolock al(mDeviceLock);
188
189 if (stream_config == NULL) {
190 ALOGE("%s:%d: NULL stream configuration array", __func__, mId);
191 return -EINVAL;
192 }
193 if (stream_config->num_streams == 0) {
194 ALOGE("%s:%d: Empty stream configuration array", __func__, mId);
195 return -EINVAL;
196 }
197
198 // Create new stream array
199 newStreams = new Stream*[stream_config->num_streams];
200 ALOGV("%s:%d: Number of Streams: %d", __func__, mId,
201 stream_config->num_streams);
202
203 // Mark all current streams unused for now
204 for (int i = 0; i < mNumStreams; i++)
205 mStreams[i]->mReuse = false;
206 // Fill new stream array with reused streams and new streams
207 for (unsigned int i = 0; i < stream_config->num_streams; i++) {
208 astream = stream_config->streams[i];
209 if (astream->max_buffers > 0) {
210 ALOGV("%s:%d: Reusing stream %d", __func__, mId, i);
211 newStreams[i] = reuseStream(astream);
212 } else {
213 ALOGV("%s:%d: Creating new stream %d", __func__, mId, i);
214 newStreams[i] = new Stream(mId, astream);
215 }
216
217 if (newStreams[i] == NULL) {
218 ALOGE("%s:%d: Error processing stream %d", __func__, mId, i);
219 goto err_out;
220 }
221 astream->priv = newStreams[i];
222 }
223
224 // Verify the set of streams in aggregate
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700225 if (!isValidStreamSet(newStreams, stream_config->num_streams,
226 stream_config->operation_mode)) {
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700227 ALOGE("%s:%d: Invalid stream set", __func__, mId);
228 goto err_out;
229 }
230
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700231 // Set up all streams (calculate usage/max_buffers for each,
232 // do any device-specific initialization)
233 res = setupStreams(newStreams, stream_config->num_streams);
234 if (res) {
235 ALOGE("%s:%d: Failed to setup stream set", __func__, mId);
236 goto err_out;
237 }
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700238
239 // Destroy all old streams and replace stream array with new one
240 destroyStreams(mStreams, mNumStreams);
241 mStreams = newStreams;
242 mNumStreams = stream_config->num_streams;
243
Ari Hausman-Cohen0b2113c2016-10-03 13:43:13 -0700244 // Update the request tracker.
245 mInFlightTracker->SetStreamConfiguration(*stream_config);
246
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700247 return 0;
248
249err_out:
250 // Clean up temporary streams, preserve existing mStreams/mNumStreams
251 destroyStreams(newStreams, stream_config->num_streams);
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700252 // Set error if it wasn't specified.
253 if (!res) {
Ari Hausman-Cohen0b2113c2016-10-03 13:43:13 -0700254 res = -EINVAL;
255 } else if (res != -EINVAL) {
256 // Fatal error, clear stream configuration.
257 mInFlightTracker->ClearStreamConfiguration();
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700258 }
259 return res;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700260}
261
262void Camera::destroyStreams(Stream **streams, int count)
263{
264 if (streams == NULL)
265 return;
266 for (int i = 0; i < count; i++) {
267 // Only destroy streams that weren't reused
268 if (streams[i] != NULL && !streams[i]->mReuse)
269 delete streams[i];
270 }
271 delete [] streams;
272}
273
274Stream *Camera::reuseStream(camera3_stream_t *astream)
275{
276 Stream *priv = reinterpret_cast<Stream*>(astream->priv);
277 // Verify the re-used stream's parameters match
278 if (!priv->isValidReuseStream(mId, astream)) {
279 ALOGE("%s:%d: Mismatched parameter in reused stream", __func__, mId);
280 return NULL;
281 }
282 // Mark stream to be reused
283 priv->mReuse = true;
284 return priv;
285}
286
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700287bool Camera::isValidStreamSet(Stream **streams, int count, uint32_t mode)
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700288{
289 int inputs = 0;
290 int outputs = 0;
291
292 if (streams == NULL) {
293 ALOGE("%s:%d: NULL stream configuration streams", __func__, mId);
294 return false;
295 }
296 if (count == 0) {
297 ALOGE("%s:%d: Zero count stream configuration streams", __func__, mId);
298 return false;
299 }
300 // Validate there is at most one input stream and at least one output stream
301 for (int i = 0; i < count; i++) {
302 // A stream may be both input and output (bidirectional)
303 if (streams[i]->isInputType())
304 inputs++;
305 if (streams[i]->isOutputType())
306 outputs++;
307 }
308 ALOGV("%s:%d: Configuring %d output streams and %d input streams",
309 __func__, mId, outputs, inputs);
310 if (outputs < 1) {
311 ALOGE("%s:%d: Stream config must have >= 1 output", __func__, mId);
312 return false;
313 }
314 if (inputs > 1) {
315 ALOGE("%s:%d: Stream config must have <= 1 input", __func__, mId);
316 return false;
317 }
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700318
319 // check for correct number of Bayer/YUV/JPEG/Encoder streams
320 return isSupportedStreamSet(streams, count, mode);
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700321}
322
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700323int Camera::setupStreams(Stream **streams, int count)
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700324{
325 /*
326 * This is where the HAL has to decide internally how to handle all of the
327 * streams, and then produce usage and max_buffer values for each stream.
328 * Note, the stream array has been checked before this point for ALL invalid
329 * conditions, so it must find a successful configuration for this stream
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700330 * array. The only errors should be from individual streams requesting
331 * unsupported features (such as data_space or rotation).
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700332 */
333 for (int i = 0; i < count; i++) {
334 uint32_t usage = 0;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700335 if (streams[i]->isOutputType())
Ari Hausman-Cohenfbac1742016-09-19 14:03:13 -0700336 usage |= GRALLOC_USAGE_SW_WRITE_OFTEN;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700337 if (streams[i]->isInputType())
Ari Hausman-Cohenfbac1742016-09-19 14:03:13 -0700338 usage |= GRALLOC_USAGE_SW_READ_OFTEN;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700339 streams[i]->setUsage(usage);
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700340
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700341 uint32_t max_buffers;
342 int res = setupStream(streams[i], &max_buffers);
343 if (res) {
344 return res;
345 }
346 streams[i]->setMaxBuffers(max_buffers);
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700347 }
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700348 return 0;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700349}
350
351bool Camera::isValidTemplateType(int type)
352{
Ari Hausman-Cohen900c1e32016-06-20 16:52:41 -0700353 return type > 0 && type < CAMERA3_TEMPLATE_COUNT;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700354}
355
356const camera_metadata_t* Camera::constructDefaultRequestSettings(int type)
357{
358 ALOGV("%s:%d: type=%d", __func__, mId, type);
359
360 if (!isValidTemplateType(type)) {
361 ALOGE("%s:%d: Invalid template request type: %d", __func__, mId, type);
362 return NULL;
363 }
Ari Hausman-Cohen49925842016-06-21 14:07:58 -0700364
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700365 if (!mTemplates[type]) {
Ari Hausman-Cohene31e1f32016-11-16 15:02:07 -0800366 // Check if the device has the necessary features
367 // for the requested template. If not, don't bother.
368 if (!mStaticInfo->TemplateSupported(type)) {
369 ALOGW("%s:%d: Camera does not support template type %d",
370 __func__, mId, type);
371 return NULL;
372 }
373
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700374 // Initialize this template if it hasn't been initialized yet.
375 std::unique_ptr<android::CameraMetadata> new_template =
376 std::make_unique<android::CameraMetadata>();
377 int res = initTemplate(type, new_template.get());
378 if (res || !new_template) {
379 ALOGE("%s:%d: Failed to generate template of type: %d",
380 __func__, mId, type);
381 return NULL;
382 }
383 mTemplates[type] = std::move(new_template);
384 }
385
386 // The "locking" here only causes non-const methods to fail,
387 // which is not a problem since the CameraMetadata being locked
388 // is already const. Destructing automatically "unlocks".
389 return mTemplates[type]->getAndLock();
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700390}
391
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700392int Camera::processCaptureRequest(camera3_capture_request_t *temp_request)
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700393{
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700394 int res;
Ari Hausman-Cohenc5a48522016-11-16 10:53:52 -0800395 // TODO(b/32917568): A capture request submitted or ongoing during a flush
396 // should be returned with an error; for now they are mutually exclusive.
397 android::Mutex::Autolock al(mFlushLock);
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700398
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700399 ATRACE_CALL();
400
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700401 if (temp_request == NULL) {
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700402 ALOGE("%s:%d: NULL request recieved", __func__, mId);
403 return -EINVAL;
404 }
405
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700406 // Make a persistent copy of request, since otherwise it won't live
407 // past the end of this method.
408 std::shared_ptr<CaptureRequest> request = std::make_shared<CaptureRequest>(temp_request);
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700409
Ari Hausman-Cohenad6fe2b2016-11-16 10:48:07 -0800410 ALOGV("%s:%d: frame: %d", __func__, mId, request->frame_number);
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700411
412 // Null/Empty indicates use last settings
413 if (request->settings.isEmpty() && !mSettingsSet) {
414 ALOGE("%s:%d: NULL settings without previous set Frame:%d",
415 __func__, mId, request->frame_number);
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700416 return -EINVAL;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700417 }
418
419 if (request->input_buffer != NULL) {
420 ALOGV("%s:%d: Reprocessing input buffer %p", __func__, mId,
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700421 request->input_buffer.get());
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700422 } else {
423 ALOGV("%s:%d: Capturing new frame.", __func__, mId);
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700424 }
425
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700426 if (!isValidRequest(*request)) {
427 ALOGE("%s:%d: Invalid request.", __func__, mId);
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700428 return -EINVAL;
429 }
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700430 // Valid settings have been provided (mSettingsSet is a misnomer;
431 // all that matters is that a previous request with valid settings
432 // has been passed to the device, not that they've been set).
433 mSettingsSet = true;
434
435 // Pre-process output buffers.
436 if (request->output_buffers.size() <= 0) {
437 ALOGE("%s:%d: Invalid number of output buffers: %d", __func__, mId,
438 request->output_buffers.size());
439 return -EINVAL;
440 }
441 for (auto& output_buffer : request->output_buffers) {
442 res = preprocessCaptureBuffer(&output_buffer);
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700443 if (res)
444 return -ENODEV;
445 }
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700446
Ari Hausman-Cohen0b2113c2016-10-03 13:43:13 -0700447 // Add the request to tracking.
448 if (!mInFlightTracker->Add(request)) {
449 ALOGE("%s:%d: Failed to track request for frame %d.",
450 __func__, mId, request->frame_number);
451 return -ENODEV;
452 }
453
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700454 // Send the request off to the device for completion.
455 enqueueRequest(request);
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700456
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700457 // Request is now in flight. The device will call completeRequest
458 // asynchronously when it is done filling buffers and metadata.
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700459 return 0;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700460}
461
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700462void Camera::completeRequest(std::shared_ptr<CaptureRequest> request, int err)
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700463{
Ari Hausman-Cohen0b2113c2016-10-03 13:43:13 -0700464 if (!mInFlightTracker->Remove(request)) {
Ari Hausman-Cohenc5a48522016-11-16 10:53:52 -0800465 ALOGE("%s:%d: Completed request %p is not being tracked. "
466 "It may have been cleared out during a flush.",
Ari Hausman-Cohen0b2113c2016-10-03 13:43:13 -0700467 __func__, mId, request.get());
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700468 return;
469 }
470
Ari Hausman-Cohen0b2113c2016-10-03 13:43:13 -0700471 // Since |request| has been removed from the tracking, this method
472 // MUST call sendResult (can still return a result in an error state, e.g.
473 // through completeRequestWithError) so the frame doesn't get lost.
474
475 if (err) {
476 ALOGE("%s:%d: Error completing request for frame %d.",
477 __func__, mId, request->frame_number);
478 completeRequestWithError(request);
479 return;
480 }
481
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700482 // Notify the framework with the shutter time (extracted from the result).
483 int64_t timestamp = 0;
484 // TODO(b/31360070): The general metadata methods should be part of the
485 // default_camera_hal namespace, not the v4l2_camera_hal namespace.
486 int res = v4l2_camera_hal::SingleTagValue(
487 request->settings, ANDROID_SENSOR_TIMESTAMP, &timestamp);
488 if (res) {
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700489 ALOGE("%s:%d: Request for frame %d is missing required metadata.",
490 __func__, mId, request->frame_number);
Ari Hausman-Cohenfb161112016-09-29 14:35:00 -0700491 // TODO(b/31653322): Send RESULT error.
492 // For now sending REQUEST error instead.
493 completeRequestWithError(request);
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700494 return;
495 }
496 notifyShutter(request->frame_number, timestamp);
497
498 // TODO(b/31653322): Check all returned buffers for errors
499 // (if any, send BUFFER error).
500
Ari Hausman-Cohenfb161112016-09-29 14:35:00 -0700501 sendResult(request);
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700502}
503
Ari Hausman-Cohenc5a48522016-11-16 10:53:52 -0800504int Camera::flush()
505{
506 ALOGV("%s:%d: Flushing.", __func__, mId);
507 // TODO(b/32917568): Synchronization. Behave "appropriately"
508 // (i.e. according to camera3.h) if process_capture_request()
509 // is called concurrently with this (in either order).
510 // Since the callback to completeRequest also may happen on a separate
511 // thread, this function should behave nicely concurrently with that too.
512 android::Mutex::Autolock al(mFlushLock);
513
514 std::set<std::shared_ptr<CaptureRequest>> requests;
515 mInFlightTracker->Clear(&requests);
516 for (auto& request : requests) {
517 // TODO(b/31653322): See camera3.h. Should return different error
518 // depending on status of the request.
519 completeRequestWithError(request);
520 }
521
522 ALOGV("%s:%d: Flushed %u requests.", __func__, mId, requests.size());
523
524 // Call down into the device flushing.
525 return flushBuffers();
526}
527
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700528int Camera::preprocessCaptureBuffer(camera3_stream_buffer_t *buffer)
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700529{
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700530 int res;
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700531 // TODO(b/29334616): This probably should be non-blocking; part
532 // of the asynchronous request processing.
533 if (buffer->acquire_fence != -1) {
534 res = sync_wait(buffer->acquire_fence, CAMERA_SYNC_TIMEOUT);
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700535 if (res == -ETIME) {
536 ALOGE("%s:%d: Timeout waiting on buffer acquire fence",
537 __func__, mId);
538 return res;
539 } else if (res) {
540 ALOGE("%s:%d: Error waiting on buffer acquire fence: %s(%d)",
541 __func__, mId, strerror(-res), res);
542 return res;
543 }
544 }
545
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700546 // Acquire fence has been waited upon.
547 buffer->acquire_fence = -1;
548 // No release fence waiting unless the device sets it.
549 buffer->release_fence = -1;
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700550
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700551 buffer->status = CAMERA3_BUFFER_STATUS_OK;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700552 return 0;
553}
554
555void Camera::notifyShutter(uint32_t frame_number, uint64_t timestamp)
556{
Ari Hausman-Cohenfb161112016-09-29 14:35:00 -0700557 camera3_notify_msg_t message;
558 memset(&message, 0, sizeof(message));
559 message.type = CAMERA3_MSG_SHUTTER;
560 message.message.shutter.frame_number = frame_number;
561 message.message.shutter.timestamp = timestamp;
562 mCallbackOps->notify(mCallbackOps, &message);
563}
564
565void Camera::completeRequestWithError(std::shared_ptr<CaptureRequest> request)
566{
567 // Send an error notification.
568 camera3_notify_msg_t message;
569 memset(&message, 0, sizeof(message));
570 message.type = CAMERA3_MSG_ERROR;
571 message.message.error.frame_number = request->frame_number;
572 message.message.error.error_stream = nullptr;
573 message.message.error.error_code = CAMERA3_MSG_ERROR_REQUEST;
574 mCallbackOps->notify(mCallbackOps, &message);
575
576 // TODO(b/31856611): Ensure all the buffers indicate their error status.
577
578 // Send the errored out result.
579 sendResult(request);
580}
581
582void Camera::sendResult(std::shared_ptr<CaptureRequest> request) {
583 // Fill in the result struct
584 // (it only needs to live until the end of the framework callback).
585 camera3_capture_result_t result {
586 request->frame_number,
587 request->settings.getAndLock(),
588 request->output_buffers.size(),
589 request->output_buffers.data(),
590 request->input_buffer.get(),
591 1 // Total result; only 1 part.
592 };
593 // Make the framework callback.
594 mCallbackOps->process_capture_result(mCallbackOps, &result);
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700595}
596
597void Camera::dump(int fd)
598{
599 ALOGV("%s:%d: Dumping to fd %d", __func__, mId, fd);
600 ATRACE_CALL();
601 android::Mutex::Autolock al(mDeviceLock);
602
603 dprintf(fd, "Camera ID: %d (Busy: %d)\n", mId, mBusy);
604
605 // TODO: dump all settings
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700606
607 dprintf(fd, "Number of streams: %d\n", mNumStreams);
608 for (int i = 0; i < mNumStreams; i++) {
609 dprintf(fd, "Stream %d/%d:\n", i, mNumStreams);
610 mStreams[i]->dump(fd);
611 }
612}
613
614const char* Camera::templateToString(int type)
615{
616 switch (type) {
617 case CAMERA3_TEMPLATE_PREVIEW:
618 return "CAMERA3_TEMPLATE_PREVIEW";
619 case CAMERA3_TEMPLATE_STILL_CAPTURE:
620 return "CAMERA3_TEMPLATE_STILL_CAPTURE";
621 case CAMERA3_TEMPLATE_VIDEO_RECORD:
622 return "CAMERA3_TEMPLATE_VIDEO_RECORD";
623 case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT:
624 return "CAMERA3_TEMPLATE_VIDEO_SNAPSHOT";
625 case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
626 return "CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG";
627 }
628 // TODO: support vendor templates
629 return "Invalid template type!";
630}
631
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700632extern "C" {
633// Get handle to camera from device priv data
634static Camera *camdev_to_camera(const camera3_device_t *dev)
635{
636 return reinterpret_cast<Camera*>(dev->priv);
637}
638
639static int initialize(const camera3_device_t *dev,
640 const camera3_callback_ops_t *callback_ops)
641{
642 return camdev_to_camera(dev)->initialize(callback_ops);
643}
644
645static int configure_streams(const camera3_device_t *dev,
646 camera3_stream_configuration_t *stream_list)
647{
648 return camdev_to_camera(dev)->configureStreams(stream_list);
649}
650
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700651static const camera_metadata_t *construct_default_request_settings(
652 const camera3_device_t *dev, int type)
653{
654 return camdev_to_camera(dev)->constructDefaultRequestSettings(type);
655}
656
657static int process_capture_request(const camera3_device_t *dev,
658 camera3_capture_request_t *request)
659{
660 return camdev_to_camera(dev)->processCaptureRequest(request);
661}
662
663static void dump(const camera3_device_t *dev, int fd)
664{
665 camdev_to_camera(dev)->dump(fd);
666}
667
Ari Hausman-Cohenc5a48522016-11-16 10:53:52 -0800668static int flush(const camera3_device_t *dev)
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700669{
Ari Hausman-Cohenc5a48522016-11-16 10:53:52 -0800670 return camdev_to_camera(dev)->flush();
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700671}
672
673} // extern "C"
674
675const camera3_device_ops_t Camera::sOps = {
676 .initialize = default_camera_hal::initialize,
677 .configure_streams = default_camera_hal::configure_streams,
Ari Hausman-Cohen900c1e32016-06-20 16:52:41 -0700678 .register_stream_buffers = nullptr,
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700679 .construct_default_request_settings
680 = default_camera_hal::construct_default_request_settings,
681 .process_capture_request = default_camera_hal::process_capture_request,
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700682 .get_metadata_vendor_tag_ops = nullptr,
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700683 .dump = default_camera_hal::dump,
684 .flush = default_camera_hal::flush,
685 .reserved = {0},
686};
687
Ari Hausman-Cohen3841a7f2016-07-19 17:27:52 -0700688} // namespace default_camera_hal