blob: 2dcf1c726b7d88a90e188e50b3b24838d842eabe [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-Cohen73442152016-06-08 15:50:49 -0700166 mBusy = false;
167 return 0;
168}
169
170int Camera::initialize(const camera3_callback_ops_t *callback_ops)
171{
172 int res;
173
174 ALOGV("%s:%d: callback_ops=%p", __func__, mId, callback_ops);
175 mCallbackOps = callback_ops;
176 // per-device specific initialization
177 res = initDevice();
178 if (res != 0) {
179 ALOGE("%s:%d: Failed to initialize device!", __func__, mId);
180 return res;
181 }
182 return 0;
183}
184
185int Camera::configureStreams(camera3_stream_configuration_t *stream_config)
186{
187 camera3_stream_t *astream;
188 Stream **newStreams = NULL;
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700189 int res = 0;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700190
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700191 // Must provide new settings after configureStreams.
192 mSettingsSet = false;
193
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700194 ALOGV("%s:%d: stream_config=%p", __func__, mId, stream_config);
195 ATRACE_CALL();
196 android::Mutex::Autolock al(mDeviceLock);
197
198 if (stream_config == NULL) {
199 ALOGE("%s:%d: NULL stream configuration array", __func__, mId);
200 return -EINVAL;
201 }
202 if (stream_config->num_streams == 0) {
203 ALOGE("%s:%d: Empty stream configuration array", __func__, mId);
204 return -EINVAL;
205 }
206
207 // Create new stream array
208 newStreams = new Stream*[stream_config->num_streams];
209 ALOGV("%s:%d: Number of Streams: %d", __func__, mId,
210 stream_config->num_streams);
211
212 // Mark all current streams unused for now
213 for (int i = 0; i < mNumStreams; i++)
214 mStreams[i]->mReuse = false;
215 // Fill new stream array with reused streams and new streams
216 for (unsigned int i = 0; i < stream_config->num_streams; i++) {
217 astream = stream_config->streams[i];
218 if (astream->max_buffers > 0) {
219 ALOGV("%s:%d: Reusing stream %d", __func__, mId, i);
220 newStreams[i] = reuseStream(astream);
221 } else {
222 ALOGV("%s:%d: Creating new stream %d", __func__, mId, i);
223 newStreams[i] = new Stream(mId, astream);
224 }
225
226 if (newStreams[i] == NULL) {
227 ALOGE("%s:%d: Error processing stream %d", __func__, mId, i);
228 goto err_out;
229 }
230 astream->priv = newStreams[i];
231 }
232
233 // Verify the set of streams in aggregate
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700234 if (!isValidStreamSet(newStreams, stream_config->num_streams,
235 stream_config->operation_mode)) {
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700236 ALOGE("%s:%d: Invalid stream set", __func__, mId);
237 goto err_out;
238 }
239
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700240 // Set up all streams (calculate usage/max_buffers for each,
241 // do any device-specific initialization)
242 res = setupStreams(newStreams, stream_config->num_streams);
243 if (res) {
244 ALOGE("%s:%d: Failed to setup stream set", __func__, mId);
245 goto err_out;
246 }
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700247
248 // Destroy all old streams and replace stream array with new one
249 destroyStreams(mStreams, mNumStreams);
250 mStreams = newStreams;
251 mNumStreams = stream_config->num_streams;
252
Ari Hausman-Cohen0b2113c2016-10-03 13:43:13 -0700253 // Update the request tracker.
254 mInFlightTracker->SetStreamConfiguration(*stream_config);
255
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700256 return 0;
257
258err_out:
259 // Clean up temporary streams, preserve existing mStreams/mNumStreams
260 destroyStreams(newStreams, stream_config->num_streams);
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700261 // Set error if it wasn't specified.
262 if (!res) {
Ari Hausman-Cohen0b2113c2016-10-03 13:43:13 -0700263 res = -EINVAL;
264 } else if (res != -EINVAL) {
265 // Fatal error, clear stream configuration.
266 mInFlightTracker->ClearStreamConfiguration();
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700267 }
268 return res;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700269}
270
271void Camera::destroyStreams(Stream **streams, int count)
272{
273 if (streams == NULL)
274 return;
275 for (int i = 0; i < count; i++) {
276 // Only destroy streams that weren't reused
277 if (streams[i] != NULL && !streams[i]->mReuse)
278 delete streams[i];
279 }
280 delete [] streams;
281}
282
283Stream *Camera::reuseStream(camera3_stream_t *astream)
284{
285 Stream *priv = reinterpret_cast<Stream*>(astream->priv);
286 // Verify the re-used stream's parameters match
287 if (!priv->isValidReuseStream(mId, astream)) {
288 ALOGE("%s:%d: Mismatched parameter in reused stream", __func__, mId);
289 return NULL;
290 }
291 // Mark stream to be reused
292 priv->mReuse = true;
293 return priv;
294}
295
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700296bool Camera::isValidStreamSet(Stream **streams, int count, uint32_t mode)
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700297{
298 int inputs = 0;
299 int outputs = 0;
300
301 if (streams == NULL) {
302 ALOGE("%s:%d: NULL stream configuration streams", __func__, mId);
303 return false;
304 }
305 if (count == 0) {
306 ALOGE("%s:%d: Zero count stream configuration streams", __func__, mId);
307 return false;
308 }
309 // Validate there is at most one input stream and at least one output stream
310 for (int i = 0; i < count; i++) {
311 // A stream may be both input and output (bidirectional)
312 if (streams[i]->isInputType())
313 inputs++;
314 if (streams[i]->isOutputType())
315 outputs++;
316 }
317 ALOGV("%s:%d: Configuring %d output streams and %d input streams",
318 __func__, mId, outputs, inputs);
319 if (outputs < 1) {
320 ALOGE("%s:%d: Stream config must have >= 1 output", __func__, mId);
321 return false;
322 }
323 if (inputs > 1) {
324 ALOGE("%s:%d: Stream config must have <= 1 input", __func__, mId);
325 return false;
326 }
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700327
328 // check for correct number of Bayer/YUV/JPEG/Encoder streams
329 return isSupportedStreamSet(streams, count, mode);
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700330}
331
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700332int Camera::setupStreams(Stream **streams, int count)
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700333{
334 /*
335 * This is where the HAL has to decide internally how to handle all of the
336 * streams, and then produce usage and max_buffer values for each stream.
337 * Note, the stream array has been checked before this point for ALL invalid
338 * conditions, so it must find a successful configuration for this stream
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700339 * array. The only errors should be from individual streams requesting
340 * unsupported features (such as data_space or rotation).
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700341 */
342 for (int i = 0; i < count; i++) {
343 uint32_t usage = 0;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700344 if (streams[i]->isOutputType())
Ari Hausman-Cohenfbac1742016-09-19 14:03:13 -0700345 usage |= GRALLOC_USAGE_SW_WRITE_OFTEN;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700346 if (streams[i]->isInputType())
Ari Hausman-Cohenfbac1742016-09-19 14:03:13 -0700347 usage |= GRALLOC_USAGE_SW_READ_OFTEN;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700348 streams[i]->setUsage(usage);
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700349
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700350 uint32_t max_buffers;
351 int res = setupStream(streams[i], &max_buffers);
352 if (res) {
353 return res;
354 }
355 streams[i]->setMaxBuffers(max_buffers);
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700356 }
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700357 return 0;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700358}
359
360bool Camera::isValidTemplateType(int type)
361{
Ari Hausman-Cohen900c1e32016-06-20 16:52:41 -0700362 return type > 0 && type < CAMERA3_TEMPLATE_COUNT;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700363}
364
365const camera_metadata_t* Camera::constructDefaultRequestSettings(int type)
366{
367 ALOGV("%s:%d: type=%d", __func__, mId, type);
368
369 if (!isValidTemplateType(type)) {
370 ALOGE("%s:%d: Invalid template request type: %d", __func__, mId, type);
371 return NULL;
372 }
Ari Hausman-Cohen49925842016-06-21 14:07:58 -0700373
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700374 if (!mTemplates[type]) {
375 // Initialize this template if it hasn't been initialized yet.
376 std::unique_ptr<android::CameraMetadata> new_template =
377 std::make_unique<android::CameraMetadata>();
378 int res = initTemplate(type, new_template.get());
379 if (res || !new_template) {
380 ALOGE("%s:%d: Failed to generate template of type: %d",
381 __func__, mId, type);
382 return NULL;
383 }
384 mTemplates[type] = std::move(new_template);
385 }
386
387 // The "locking" here only causes non-const methods to fail,
388 // which is not a problem since the CameraMetadata being locked
389 // is already const. Destructing automatically "unlocks".
390 return mTemplates[type]->getAndLock();
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700391}
392
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700393int Camera::processCaptureRequest(camera3_capture_request_t *temp_request)
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700394{
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700395 int res;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700396
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700397 ATRACE_CALL();
398
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700399 if (temp_request == NULL) {
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700400 ALOGE("%s:%d: NULL request recieved", __func__, mId);
401 return -EINVAL;
402 }
403
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700404 // Make a persistent copy of request, since otherwise it won't live
405 // past the end of this method.
406 std::shared_ptr<CaptureRequest> request = std::make_shared<CaptureRequest>(temp_request);
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700407
Ari Hausman-Cohenad6fe2b2016-11-16 10:48:07 -0800408 ALOGV("%s:%d: frame: %d", __func__, mId, request->frame_number);
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700409
410 // Null/Empty indicates use last settings
411 if (request->settings.isEmpty() && !mSettingsSet) {
412 ALOGE("%s:%d: NULL settings without previous set Frame:%d",
413 __func__, mId, request->frame_number);
Ari Hausman-Cohenabbf9cc2016-08-23 11:59:59 -0700414 return -EINVAL;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700415 }
416
417 if (request->input_buffer != NULL) {
418 ALOGV("%s:%d: Reprocessing input buffer %p", __func__, mId,
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700419 request->input_buffer.get());
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700420 } else {
421 ALOGV("%s:%d: Capturing new frame.", __func__, mId);
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700422 }
423
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700424 if (!isValidRequest(*request)) {
425 ALOGE("%s:%d: Invalid request.", __func__, mId);
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700426 return -EINVAL;
427 }
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700428 // Valid settings have been provided (mSettingsSet is a misnomer;
429 // all that matters is that a previous request with valid settings
430 // has been passed to the device, not that they've been set).
431 mSettingsSet = true;
432
433 // Pre-process output buffers.
434 if (request->output_buffers.size() <= 0) {
435 ALOGE("%s:%d: Invalid number of output buffers: %d", __func__, mId,
436 request->output_buffers.size());
437 return -EINVAL;
438 }
439 for (auto& output_buffer : request->output_buffers) {
440 res = preprocessCaptureBuffer(&output_buffer);
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700441 if (res)
442 return -ENODEV;
443 }
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700444
Ari Hausman-Cohen0b2113c2016-10-03 13:43:13 -0700445 // Add the request to tracking.
446 if (!mInFlightTracker->Add(request)) {
447 ALOGE("%s:%d: Failed to track request for frame %d.",
448 __func__, mId, request->frame_number);
449 return -ENODEV;
450 }
451
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700452 // Send the request off to the device for completion.
453 enqueueRequest(request);
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700454
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700455 // Request is now in flight. The device will call completeRequest
456 // asynchronously when it is done filling buffers and metadata.
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700457 return 0;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700458}
459
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700460void Camera::completeRequest(std::shared_ptr<CaptureRequest> request, int err)
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700461{
Ari Hausman-Cohen0b2113c2016-10-03 13:43:13 -0700462 if (!mInFlightTracker->Remove(request)) {
463 ALOGE("%s:%d: Completed request %p is not being tracked.",
464 __func__, mId, request.get());
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700465 return;
466 }
467
Ari Hausman-Cohen0b2113c2016-10-03 13:43:13 -0700468 // Since |request| has been removed from the tracking, this method
469 // MUST call sendResult (can still return a result in an error state, e.g.
470 // through completeRequestWithError) so the frame doesn't get lost.
471
472 if (err) {
473 ALOGE("%s:%d: Error completing request for frame %d.",
474 __func__, mId, request->frame_number);
475 completeRequestWithError(request);
476 return;
477 }
478
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700479 // Notify the framework with the shutter time (extracted from the result).
480 int64_t timestamp = 0;
481 // TODO(b/31360070): The general metadata methods should be part of the
482 // default_camera_hal namespace, not the v4l2_camera_hal namespace.
483 int res = v4l2_camera_hal::SingleTagValue(
484 request->settings, ANDROID_SENSOR_TIMESTAMP, &timestamp);
485 if (res) {
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700486 ALOGE("%s:%d: Request for frame %d is missing required metadata.",
487 __func__, mId, request->frame_number);
Ari Hausman-Cohenfb161112016-09-29 14:35:00 -0700488 // TODO(b/31653322): Send RESULT error.
489 // For now sending REQUEST error instead.
490 completeRequestWithError(request);
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700491 return;
492 }
493 notifyShutter(request->frame_number, timestamp);
494
495 // TODO(b/31653322): Check all returned buffers for errors
496 // (if any, send BUFFER error).
497
Ari Hausman-Cohenfb161112016-09-29 14:35:00 -0700498 sendResult(request);
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700499}
500
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700501int Camera::preprocessCaptureBuffer(camera3_stream_buffer_t *buffer)
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700502{
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700503 int res;
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700504 // TODO(b/29334616): This probably should be non-blocking; part
505 // of the asynchronous request processing.
506 if (buffer->acquire_fence != -1) {
507 res = sync_wait(buffer->acquire_fence, CAMERA_SYNC_TIMEOUT);
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700508 if (res == -ETIME) {
509 ALOGE("%s:%d: Timeout waiting on buffer acquire fence",
510 __func__, mId);
511 return res;
512 } else if (res) {
513 ALOGE("%s:%d: Error waiting on buffer acquire fence: %s(%d)",
514 __func__, mId, strerror(-res), res);
515 return res;
516 }
517 }
518
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700519 // Acquire fence has been waited upon.
520 buffer->acquire_fence = -1;
521 // No release fence waiting unless the device sets it.
522 buffer->release_fence = -1;
Ari Hausman-Cohen24e541c2016-07-21 11:20:30 -0700523
Ari Hausman-Cohen2738a9c2016-09-21 15:03:49 -0700524 buffer->status = CAMERA3_BUFFER_STATUS_OK;
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700525 return 0;
526}
527
528void Camera::notifyShutter(uint32_t frame_number, uint64_t timestamp)
529{
Ari Hausman-Cohenfb161112016-09-29 14:35:00 -0700530 camera3_notify_msg_t message;
531 memset(&message, 0, sizeof(message));
532 message.type = CAMERA3_MSG_SHUTTER;
533 message.message.shutter.frame_number = frame_number;
534 message.message.shutter.timestamp = timestamp;
535 mCallbackOps->notify(mCallbackOps, &message);
536}
537
538void Camera::completeRequestWithError(std::shared_ptr<CaptureRequest> request)
539{
540 // Send an error notification.
541 camera3_notify_msg_t message;
542 memset(&message, 0, sizeof(message));
543 message.type = CAMERA3_MSG_ERROR;
544 message.message.error.frame_number = request->frame_number;
545 message.message.error.error_stream = nullptr;
546 message.message.error.error_code = CAMERA3_MSG_ERROR_REQUEST;
547 mCallbackOps->notify(mCallbackOps, &message);
548
549 // TODO(b/31856611): Ensure all the buffers indicate their error status.
550
551 // Send the errored out result.
552 sendResult(request);
553}
554
555void Camera::sendResult(std::shared_ptr<CaptureRequest> request) {
556 // Fill in the result struct
557 // (it only needs to live until the end of the framework callback).
558 camera3_capture_result_t result {
559 request->frame_number,
560 request->settings.getAndLock(),
561 request->output_buffers.size(),
562 request->output_buffers.data(),
563 request->input_buffer.get(),
564 1 // Total result; only 1 part.
565 };
566 // Make the framework callback.
567 mCallbackOps->process_capture_result(mCallbackOps, &result);
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700568}
569
570void Camera::dump(int fd)
571{
572 ALOGV("%s:%d: Dumping to fd %d", __func__, mId, fd);
573 ATRACE_CALL();
574 android::Mutex::Autolock al(mDeviceLock);
575
576 dprintf(fd, "Camera ID: %d (Busy: %d)\n", mId, mBusy);
577
578 // TODO: dump all settings
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700579
580 dprintf(fd, "Number of streams: %d\n", mNumStreams);
581 for (int i = 0; i < mNumStreams; i++) {
582 dprintf(fd, "Stream %d/%d:\n", i, mNumStreams);
583 mStreams[i]->dump(fd);
584 }
585}
586
587const char* Camera::templateToString(int type)
588{
589 switch (type) {
590 case CAMERA3_TEMPLATE_PREVIEW:
591 return "CAMERA3_TEMPLATE_PREVIEW";
592 case CAMERA3_TEMPLATE_STILL_CAPTURE:
593 return "CAMERA3_TEMPLATE_STILL_CAPTURE";
594 case CAMERA3_TEMPLATE_VIDEO_RECORD:
595 return "CAMERA3_TEMPLATE_VIDEO_RECORD";
596 case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT:
597 return "CAMERA3_TEMPLATE_VIDEO_SNAPSHOT";
598 case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
599 return "CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG";
600 }
601 // TODO: support vendor templates
602 return "Invalid template type!";
603}
604
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700605extern "C" {
606// Get handle to camera from device priv data
607static Camera *camdev_to_camera(const camera3_device_t *dev)
608{
609 return reinterpret_cast<Camera*>(dev->priv);
610}
611
612static int initialize(const camera3_device_t *dev,
613 const camera3_callback_ops_t *callback_ops)
614{
615 return camdev_to_camera(dev)->initialize(callback_ops);
616}
617
618static int configure_streams(const camera3_device_t *dev,
619 camera3_stream_configuration_t *stream_list)
620{
621 return camdev_to_camera(dev)->configureStreams(stream_list);
622}
623
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700624static const camera_metadata_t *construct_default_request_settings(
625 const camera3_device_t *dev, int type)
626{
627 return camdev_to_camera(dev)->constructDefaultRequestSettings(type);
628}
629
630static int process_capture_request(const camera3_device_t *dev,
631 camera3_capture_request_t *request)
632{
633 return camdev_to_camera(dev)->processCaptureRequest(request);
634}
635
636static void dump(const camera3_device_t *dev, int fd)
637{
638 camdev_to_camera(dev)->dump(fd);
639}
640
641static int flush(const camera3_device_t*)
642{
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700643 // TODO(b/29937783)
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700644 ALOGE("%s: unimplemented.", __func__);
645 return -1;
646}
647
648} // extern "C"
649
650const camera3_device_ops_t Camera::sOps = {
651 .initialize = default_camera_hal::initialize,
652 .configure_streams = default_camera_hal::configure_streams,
Ari Hausman-Cohen900c1e32016-06-20 16:52:41 -0700653 .register_stream_buffers = nullptr,
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700654 .construct_default_request_settings
655 = default_camera_hal::construct_default_request_settings,
656 .process_capture_request = default_camera_hal::process_capture_request,
Ari Hausman-Cohen72fddb32016-06-30 16:53:31 -0700657 .get_metadata_vendor_tag_ops = nullptr,
Ari Hausman-Cohen73442152016-06-08 15:50:49 -0700658 .dump = default_camera_hal::dump,
659 .flush = default_camera_hal::flush,
660 .reserved = {0},
661};
662
Ari Hausman-Cohen3841a7f2016-07-19 17:27:52 -0700663} // namespace default_camera_hal