blob: dc9c8257eca7d1fa0f5ec08e24a6f2f2e6795f1c [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{
100 android::Mutex::Autolock al(mStaticInfoLock);
101
102 info->device_version = mDevice.common.version;
103 initDeviceInfo(info);
104 if (mStaticInfo == NULL) {
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700105 std::unique_ptr<android::CameraMetadata> static_info =
106 std::make_unique<android::CameraMetadata>();
107 if (initStaticInfo(static_info.get())) {
108 return -ENODEV;
109 }
110 mStaticInfo = std::move(static_info);
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700111 }
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700112 // The "locking" here only causes non-const methods to fail,
113 // which is not a problem since the CameraMetadata being locked
114 // is already const. Destructing automatically "unlocks".
115 info->static_camera_characteristics = mStaticInfo->getAndLock();
116
117 // Get facing & orientation from the static info.
118 uint8_t facing = 0;
119 int res = v4l2_camera_hal::SingleTagValue(
120 *mStaticInfo, ANDROID_LENS_FACING, &facing);
121 if (res) {
122 ALOGE("%s:%d: Failed to get facing from static metadata.",
123 __func__, mId);
124 return res;
125 }
126 switch (facing) {
127 case (ANDROID_LENS_FACING_FRONT):
128 info->facing = CAMERA_FACING_FRONT;
129 break;
130 case (ANDROID_LENS_FACING_BACK):
131 info->facing = CAMERA_FACING_BACK;
132 break;
133 case (ANDROID_LENS_FACING_EXTERNAL):
134 info->facing = CAMERA_FACING_EXTERNAL;
135 break;
136 default:
137 ALOGE("%s:%d: Invalid facing from metadata: %d.",
138 __func__, mId, facing);
139 return -ENODEV;
140 }
141 int32_t orientation = 0;
142 res = v4l2_camera_hal::SingleTagValue(
143 *mStaticInfo, ANDROID_SENSOR_ORIENTATION, &orientation);
144 if (res) {
145 ALOGE("%s:%d: Failed to get orientation from static metadata.",
146 __func__, mId);
147 return res;
148 }
149 info->orientation = static_cast<int>(orientation);
150
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700151 return 0;
152}
153
154int Camera::close()
155{
156 ALOGI("%s:%d: Closing camera device", __func__, mId);
157 ATRACE_CALL();
158 android::Mutex::Autolock al(mDeviceLock);
159
160 if (!mBusy) {
161 ALOGE("%s:%d: Error! Camera device not open", __func__, mId);
162 return -EINVAL;
163 }
164
Ari Hausman-Cohen345bd3a2016-06-13 15:33:53 -0700165 disconnect();
Ari Hausman-Cohenc5a48522016-11-16 10:53:52 -0800166 flush();
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700167 mBusy = false;
168 return 0;
169}
170
171int Camera::initialize(const camera3_callback_ops_t *callback_ops)
172{
173 int res;
174
175 ALOGV("%s:%d: callback_ops=%p", __func__, mId, callback_ops);
176 mCallbackOps = callback_ops;
177 // per-device specific initialization
178 res = initDevice();
179 if (res != 0) {
180 ALOGE("%s:%d: Failed to initialize device!", __func__, mId);
181 return res;
182 }
183 return 0;
184}
185
186int Camera::configureStreams(camera3_stream_configuration_t *stream_config)
187{
188 camera3_stream_t *astream;
189 Stream **newStreams = NULL;
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700190 int res = 0;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700191
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700192 // Must provide new settings after configureStreams.
193 mSettingsSet = false;
194
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700195 ALOGV("%s:%d: stream_config=%p", __func__, mId, stream_config);
196 ATRACE_CALL();
197 android::Mutex::Autolock al(mDeviceLock);
198
199 if (stream_config == NULL) {
200 ALOGE("%s:%d: NULL stream configuration array", __func__, mId);
201 return -EINVAL;
202 }
203 if (stream_config->num_streams == 0) {
204 ALOGE("%s:%d: Empty stream configuration array", __func__, mId);
205 return -EINVAL;
206 }
207
208 // Create new stream array
209 newStreams = new Stream*[stream_config->num_streams];
210 ALOGV("%s:%d: Number of Streams: %d", __func__, mId,
211 stream_config->num_streams);
212
213 // Mark all current streams unused for now
214 for (int i = 0; i < mNumStreams; i++)
215 mStreams[i]->mReuse = false;
216 // Fill new stream array with reused streams and new streams
217 for (unsigned int i = 0; i < stream_config->num_streams; i++) {
218 astream = stream_config->streams[i];
219 if (astream->max_buffers > 0) {
220 ALOGV("%s:%d: Reusing stream %d", __func__, mId, i);
221 newStreams[i] = reuseStream(astream);
222 } else {
223 ALOGV("%s:%d: Creating new stream %d", __func__, mId, i);
224 newStreams[i] = new Stream(mId, astream);
225 }
226
227 if (newStreams[i] == NULL) {
228 ALOGE("%s:%d: Error processing stream %d", __func__, mId, i);
229 goto err_out;
230 }
231 astream->priv = newStreams[i];
232 }
233
234 // Verify the set of streams in aggregate
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700235 if (!isValidStreamSet(newStreams, stream_config->num_streams,
236 stream_config->operation_mode)) {
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700237 ALOGE("%s:%d: Invalid stream set", __func__, mId);
238 goto err_out;
239 }
240
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700241 // Set up all streams (calculate usage/max_buffers for each,
242 // do any device-specific initialization)
243 res = setupStreams(newStreams, stream_config->num_streams);
244 if (res) {
245 ALOGE("%s:%d: Failed to setup stream set", __func__, mId);
246 goto err_out;
247 }
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700248
249 // Destroy all old streams and replace stream array with new one
250 destroyStreams(mStreams, mNumStreams);
251 mStreams = newStreams;
252 mNumStreams = stream_config->num_streams;
253
Ari Hausman-Cohen0b2113c2016-10-03 13:43:13 -0700254 // Update the request tracker.
255 mInFlightTracker->SetStreamConfiguration(*stream_config);
256
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700257 return 0;
258
259err_out:
260 // Clean up temporary streams, preserve existing mStreams/mNumStreams
261 destroyStreams(newStreams, stream_config->num_streams);
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700262 // Set error if it wasn't specified.
263 if (!res) {
Ari Hausman-Cohen0b2113c2016-10-03 13:43:13 -0700264 res = -EINVAL;
265 } else if (res != -EINVAL) {
266 // Fatal error, clear stream configuration.
267 mInFlightTracker->ClearStreamConfiguration();
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700268 }
269 return res;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700270}
271
272void Camera::destroyStreams(Stream **streams, int count)
273{
274 if (streams == NULL)
275 return;
276 for (int i = 0; i < count; i++) {
277 // Only destroy streams that weren't reused
278 if (streams[i] != NULL && !streams[i]->mReuse)
279 delete streams[i];
280 }
281 delete [] streams;
282}
283
284Stream *Camera::reuseStream(camera3_stream_t *astream)
285{
286 Stream *priv = reinterpret_cast<Stream*>(astream->priv);
287 // Verify the re-used stream's parameters match
288 if (!priv->isValidReuseStream(mId, astream)) {
289 ALOGE("%s:%d: Mismatched parameter in reused stream", __func__, mId);
290 return NULL;
291 }
292 // Mark stream to be reused
293 priv->mReuse = true;
294 return priv;
295}
296
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700297bool Camera::isValidStreamSet(Stream **streams, int count, uint32_t mode)
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700298{
299 int inputs = 0;
300 int outputs = 0;
301
302 if (streams == NULL) {
303 ALOGE("%s:%d: NULL stream configuration streams", __func__, mId);
304 return false;
305 }
306 if (count == 0) {
307 ALOGE("%s:%d: Zero count stream configuration streams", __func__, mId);
308 return false;
309 }
310 // Validate there is at most one input stream and at least one output stream
311 for (int i = 0; i < count; i++) {
312 // A stream may be both input and output (bidirectional)
313 if (streams[i]->isInputType())
314 inputs++;
315 if (streams[i]->isOutputType())
316 outputs++;
317 }
318 ALOGV("%s:%d: Configuring %d output streams and %d input streams",
319 __func__, mId, outputs, inputs);
320 if (outputs < 1) {
321 ALOGE("%s:%d: Stream config must have >= 1 output", __func__, mId);
322 return false;
323 }
324 if (inputs > 1) {
325 ALOGE("%s:%d: Stream config must have <= 1 input", __func__, mId);
326 return false;
327 }
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700328
329 // check for correct number of Bayer/YUV/JPEG/Encoder streams
330 return isSupportedStreamSet(streams, count, mode);
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700331}
332
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700333int Camera::setupStreams(Stream **streams, int count)
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700334{
335 /*
336 * This is where the HAL has to decide internally how to handle all of the
337 * streams, and then produce usage and max_buffer values for each stream.
338 * Note, the stream array has been checked before this point for ALL invalid
339 * conditions, so it must find a successful configuration for this stream
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700340 * array. The only errors should be from individual streams requesting
341 * unsupported features (such as data_space or rotation).
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700342 */
343 for (int i = 0; i < count; i++) {
344 uint32_t usage = 0;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700345 if (streams[i]->isOutputType())
Ari Hausman-Cohenfbac1742016-09-19 14:03:13 -0700346 usage |= GRALLOC_USAGE_SW_WRITE_OFTEN;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700347 if (streams[i]->isInputType())
Ari Hausman-Cohenfbac1742016-09-19 14:03:13 -0700348 usage |= GRALLOC_USAGE_SW_READ_OFTEN;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700349 streams[i]->setUsage(usage);
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700350
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700351 uint32_t max_buffers;
352 int res = setupStream(streams[i], &max_buffers);
353 if (res) {
354 return res;
355 }
356 streams[i]->setMaxBuffers(max_buffers);
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700357 }
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700358 return 0;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700359}
360
361bool Camera::isValidTemplateType(int type)
362{
Ari Hausman-Cohen900c1e32016-06-20 16:52:41 -0700363 return type > 0 && type < CAMERA3_TEMPLATE_COUNT;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700364}
365
366const camera_metadata_t* Camera::constructDefaultRequestSettings(int type)
367{
368 ALOGV("%s:%d: type=%d", __func__, mId, type);
369
370 if (!isValidTemplateType(type)) {
371 ALOGE("%s:%d: Invalid template request type: %d", __func__, mId, type);
372 return NULL;
373 }
Ari Hausman-Cohen49925842016-06-21 14:07:58 -0700374
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700375 if (!mTemplates[type]) {
376 // Initialize this template if it hasn't been initialized yet.
377 std::unique_ptr<android::CameraMetadata> new_template =
378 std::make_unique<android::CameraMetadata>();
379 int res = initTemplate(type, new_template.get());
380 if (res || !new_template) {
381 ALOGE("%s:%d: Failed to generate template of type: %d",
382 __func__, mId, type);
383 return NULL;
384 }
385 mTemplates[type] = std::move(new_template);
386 }
387
388 // The "locking" here only causes non-const methods to fail,
389 // which is not a problem since the CameraMetadata being locked
390 // is already const. Destructing automatically "unlocks".
391 return mTemplates[type]->getAndLock();
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700392}
393
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700394int Camera::processCaptureRequest(camera3_capture_request_t *temp_request)
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700395{
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700396 int res;
Ari Hausman-Cohenc5a48522016-11-16 10:53:52 -0800397 // TODO(b/32917568): A capture request submitted or ongoing during a flush
398 // should be returned with an error; for now they are mutually exclusive.
399 android::Mutex::Autolock al(mFlushLock);
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700400
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700401 ATRACE_CALL();
402
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700403 if (temp_request == NULL) {
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700404 ALOGE("%s:%d: NULL request recieved", __func__, mId);
405 return -EINVAL;
406 }
407
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700408 // Make a persistent copy of request, since otherwise it won't live
409 // past the end of this method.
410 std::shared_ptr<CaptureRequest> request = std::make_shared<CaptureRequest>(temp_request);
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700411
Ari Hausman-Cohenad6fe2b2016-11-16 10:48:07 -0800412 ALOGV("%s:%d: frame: %d", __func__, mId, request->frame_number);
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700413
414 // Null/Empty indicates use last settings
415 if (request->settings.isEmpty() && !mSettingsSet) {
416 ALOGE("%s:%d: NULL settings without previous set Frame:%d",
417 __func__, mId, request->frame_number);
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700418 return -EINVAL;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700419 }
420
421 if (request->input_buffer != NULL) {
422 ALOGV("%s:%d: Reprocessing input buffer %p", __func__, mId,
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700423 request->input_buffer.get());
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700424 } else {
425 ALOGV("%s:%d: Capturing new frame.", __func__, mId);
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700426 }
427
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700428 if (!isValidRequest(*request)) {
429 ALOGE("%s:%d: Invalid request.", __func__, mId);
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700430 return -EINVAL;
431 }
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700432 // Valid settings have been provided (mSettingsSet is a misnomer;
433 // all that matters is that a previous request with valid settings
434 // has been passed to the device, not that they've been set).
435 mSettingsSet = true;
436
437 // Pre-process output buffers.
438 if (request->output_buffers.size() <= 0) {
439 ALOGE("%s:%d: Invalid number of output buffers: %d", __func__, mId,
440 request->output_buffers.size());
441 return -EINVAL;
442 }
443 for (auto& output_buffer : request->output_buffers) {
444 res = preprocessCaptureBuffer(&output_buffer);
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700445 if (res)
446 return -ENODEV;
447 }
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700448
Ari Hausman-Cohen0b2113c2016-10-03 13:43:13 -0700449 // Add the request to tracking.
450 if (!mInFlightTracker->Add(request)) {
451 ALOGE("%s:%d: Failed to track request for frame %d.",
452 __func__, mId, request->frame_number);
453 return -ENODEV;
454 }
455
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700456 // Send the request off to the device for completion.
457 enqueueRequest(request);
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700458
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700459 // Request is now in flight. The device will call completeRequest
460 // asynchronously when it is done filling buffers and metadata.
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700461 return 0;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700462}
463
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700464void Camera::completeRequest(std::shared_ptr<CaptureRequest> request, int err)
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700465{
Ari Hausman-Cohen0b2113c2016-10-03 13:43:13 -0700466 if (!mInFlightTracker->Remove(request)) {
Ari Hausman-Cohenc5a48522016-11-16 10:53:52 -0800467 ALOGE("%s:%d: Completed request %p is not being tracked. "
468 "It may have been cleared out during a flush.",
Ari Hausman-Cohen0b2113c2016-10-03 13:43:13 -0700469 __func__, mId, request.get());
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700470 return;
471 }
472
Ari Hausman-Cohen0b2113c2016-10-03 13:43:13 -0700473 // Since |request| has been removed from the tracking, this method
474 // MUST call sendResult (can still return a result in an error state, e.g.
475 // through completeRequestWithError) so the frame doesn't get lost.
476
477 if (err) {
478 ALOGE("%s:%d: Error completing request for frame %d.",
479 __func__, mId, request->frame_number);
480 completeRequestWithError(request);
481 return;
482 }
483
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700484 // Notify the framework with the shutter time (extracted from the result).
485 int64_t timestamp = 0;
486 // TODO(b/31360070): The general metadata methods should be part of the
487 // default_camera_hal namespace, not the v4l2_camera_hal namespace.
488 int res = v4l2_camera_hal::SingleTagValue(
489 request->settings, ANDROID_SENSOR_TIMESTAMP, &timestamp);
490 if (res) {
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700491 ALOGE("%s:%d: Request for frame %d is missing required metadata.",
492 __func__, mId, request->frame_number);
Ari Hausman-Cohenfb161112016-09-29 14:35:00 -0700493 // TODO(b/31653322): Send RESULT error.
494 // For now sending REQUEST error instead.
495 completeRequestWithError(request);
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700496 return;
497 }
498 notifyShutter(request->frame_number, timestamp);
499
500 // TODO(b/31653322): Check all returned buffers for errors
501 // (if any, send BUFFER error).
502
Ari Hausman-Cohenfb161112016-09-29 14:35:00 -0700503 sendResult(request);
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700504}
505
Ari Hausman-Cohenc5a48522016-11-16 10:53:52 -0800506int Camera::flush()
507{
508 ALOGV("%s:%d: Flushing.", __func__, mId);
509 // TODO(b/32917568): Synchronization. Behave "appropriately"
510 // (i.e. according to camera3.h) if process_capture_request()
511 // is called concurrently with this (in either order).
512 // Since the callback to completeRequest also may happen on a separate
513 // thread, this function should behave nicely concurrently with that too.
514 android::Mutex::Autolock al(mFlushLock);
515
516 std::set<std::shared_ptr<CaptureRequest>> requests;
517 mInFlightTracker->Clear(&requests);
518 for (auto& request : requests) {
519 // TODO(b/31653322): See camera3.h. Should return different error
520 // depending on status of the request.
521 completeRequestWithError(request);
522 }
523
524 ALOGV("%s:%d: Flushed %u requests.", __func__, mId, requests.size());
525
526 // Call down into the device flushing.
527 return flushBuffers();
528}
529
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700530int Camera::preprocessCaptureBuffer(camera3_stream_buffer_t *buffer)
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700531{
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700532 int res;
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700533 // TODO(b/29334616): This probably should be non-blocking; part
534 // of the asynchronous request processing.
535 if (buffer->acquire_fence != -1) {
536 res = sync_wait(buffer->acquire_fence, CAMERA_SYNC_TIMEOUT);
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700537 if (res == -ETIME) {
538 ALOGE("%s:%d: Timeout waiting on buffer acquire fence",
539 __func__, mId);
540 return res;
541 } else if (res) {
542 ALOGE("%s:%d: Error waiting on buffer acquire fence: %s(%d)",
543 __func__, mId, strerror(-res), res);
544 return res;
545 }
546 }
547
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700548 // Acquire fence has been waited upon.
549 buffer->acquire_fence = -1;
550 // No release fence waiting unless the device sets it.
551 buffer->release_fence = -1;
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700552
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700553 buffer->status = CAMERA3_BUFFER_STATUS_OK;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700554 return 0;
555}
556
557void Camera::notifyShutter(uint32_t frame_number, uint64_t timestamp)
558{
Ari Hausman-Cohenfb161112016-09-29 14:35:00 -0700559 camera3_notify_msg_t message;
560 memset(&message, 0, sizeof(message));
561 message.type = CAMERA3_MSG_SHUTTER;
562 message.message.shutter.frame_number = frame_number;
563 message.message.shutter.timestamp = timestamp;
564 mCallbackOps->notify(mCallbackOps, &message);
565}
566
567void Camera::completeRequestWithError(std::shared_ptr<CaptureRequest> request)
568{
569 // Send an error notification.
570 camera3_notify_msg_t message;
571 memset(&message, 0, sizeof(message));
572 message.type = CAMERA3_MSG_ERROR;
573 message.message.error.frame_number = request->frame_number;
574 message.message.error.error_stream = nullptr;
575 message.message.error.error_code = CAMERA3_MSG_ERROR_REQUEST;
576 mCallbackOps->notify(mCallbackOps, &message);
577
578 // TODO(b/31856611): Ensure all the buffers indicate their error status.
579
580 // Send the errored out result.
581 sendResult(request);
582}
583
584void Camera::sendResult(std::shared_ptr<CaptureRequest> request) {
585 // Fill in the result struct
586 // (it only needs to live until the end of the framework callback).
587 camera3_capture_result_t result {
588 request->frame_number,
589 request->settings.getAndLock(),
590 request->output_buffers.size(),
591 request->output_buffers.data(),
592 request->input_buffer.get(),
593 1 // Total result; only 1 part.
594 };
595 // Make the framework callback.
596 mCallbackOps->process_capture_result(mCallbackOps, &result);
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700597}
598
599void Camera::dump(int fd)
600{
601 ALOGV("%s:%d: Dumping to fd %d", __func__, mId, fd);
602 ATRACE_CALL();
603 android::Mutex::Autolock al(mDeviceLock);
604
605 dprintf(fd, "Camera ID: %d (Busy: %d)\n", mId, mBusy);
606
607 // TODO: dump all settings
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700608
609 dprintf(fd, "Number of streams: %d\n", mNumStreams);
610 for (int i = 0; i < mNumStreams; i++) {
611 dprintf(fd, "Stream %d/%d:\n", i, mNumStreams);
612 mStreams[i]->dump(fd);
613 }
614}
615
616const char* Camera::templateToString(int type)
617{
618 switch (type) {
619 case CAMERA3_TEMPLATE_PREVIEW:
620 return "CAMERA3_TEMPLATE_PREVIEW";
621 case CAMERA3_TEMPLATE_STILL_CAPTURE:
622 return "CAMERA3_TEMPLATE_STILL_CAPTURE";
623 case CAMERA3_TEMPLATE_VIDEO_RECORD:
624 return "CAMERA3_TEMPLATE_VIDEO_RECORD";
625 case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT:
626 return "CAMERA3_TEMPLATE_VIDEO_SNAPSHOT";
627 case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
628 return "CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG";
629 }
630 // TODO: support vendor templates
631 return "Invalid template type!";
632}
633
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700634extern "C" {
635// Get handle to camera from device priv data
636static Camera *camdev_to_camera(const camera3_device_t *dev)
637{
638 return reinterpret_cast<Camera*>(dev->priv);
639}
640
641static int initialize(const camera3_device_t *dev,
642 const camera3_callback_ops_t *callback_ops)
643{
644 return camdev_to_camera(dev)->initialize(callback_ops);
645}
646
647static int configure_streams(const camera3_device_t *dev,
648 camera3_stream_configuration_t *stream_list)
649{
650 return camdev_to_camera(dev)->configureStreams(stream_list);
651}
652
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700653static const camera_metadata_t *construct_default_request_settings(
654 const camera3_device_t *dev, int type)
655{
656 return camdev_to_camera(dev)->constructDefaultRequestSettings(type);
657}
658
659static int process_capture_request(const camera3_device_t *dev,
660 camera3_capture_request_t *request)
661{
662 return camdev_to_camera(dev)->processCaptureRequest(request);
663}
664
665static void dump(const camera3_device_t *dev, int fd)
666{
667 camdev_to_camera(dev)->dump(fd);
668}
669
Ari Hausman-Cohenc5a48522016-11-16 10:53:52 -0800670static int flush(const camera3_device_t *dev)
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700671{
Ari Hausman-Cohenc5a48522016-11-16 10:53:52 -0800672 return camdev_to_camera(dev)->flush();
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700673}
674
675} // extern "C"
676
677const camera3_device_ops_t Camera::sOps = {
678 .initialize = default_camera_hal::initialize,
679 .configure_streams = default_camera_hal::configure_streams,
Ari Hausman-Cohen900c1e32016-06-20 16:52:41 -0700680 .register_stream_buffers = nullptr,
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700681 .construct_default_request_settings
682 = default_camera_hal::construct_default_request_settings,
683 .process_capture_request = default_camera_hal::process_capture_request,
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700684 .get_metadata_vendor_tag_ops = nullptr,
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700685 .dump = default_camera_hal::dump,
686 .flush = default_camera_hal::flush,
687 .reserved = {0},
688};
689
Ari Hausman-Cohen3841a7f2016-07-19 17:27:52 -0700690} // namespace default_camera_hal