blob: b06f65dd4868819b929520d06421909e53876aee [file] [log] [blame]
Alex Ray7ee0b7a2012-11-06 00:12:49 -08001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <cstdlib>
18#include <pthread.h>
Alex Raya0ed4be2013-02-25 15:02:16 -080019#include <hardware/camera3.h>
20#include "CameraHAL.h"
Alex Raybcaf7882013-02-28 16:04:35 -080021#include "Stream.h"
Alex Ray7ee0b7a2012-11-06 00:12:49 -080022
Alex Rayed6b8a72012-12-27 10:42:22 -080023//#define LOG_NDEBUG 0
Alex Ray7ee0b7a2012-11-06 00:12:49 -080024#define LOG_TAG "Camera"
25#include <cutils/log.h>
26
Alex Rayed6b8a72012-12-27 10:42:22 -080027#define ATRACE_TAG (ATRACE_TAG_CAMERA | ATRACE_TAG_HAL)
28#include <cutils/trace.h>
Alex Rayc16e56d2013-04-29 12:24:49 -070029#include "ScopedTrace.h"
Alex Rayed6b8a72012-12-27 10:42:22 -080030
Alex Ray7ee0b7a2012-11-06 00:12:49 -080031#include "Camera.h"
32
33namespace default_camera_hal {
34
35extern "C" {
36// Shim passed to the framework to close an opened device.
37static int close_device(hw_device_t* dev)
38{
Alex Raya0ed4be2013-02-25 15:02:16 -080039 camera3_device_t* cam_dev = reinterpret_cast<camera3_device_t*>(dev);
Alex Ray7ee0b7a2012-11-06 00:12:49 -080040 Camera* cam = static_cast<Camera*>(cam_dev->priv);
41 return cam->close();
42}
43} // extern "C"
44
Alex Raya0ed4be2013-02-25 15:02:16 -080045Camera::Camera(int id)
46 : mId(id),
47 mBusy(false),
Alex Raybcaf7882013-02-28 16:04:35 -080048 mCallbackOps(NULL),
49 mStreams(NULL),
50 mNumStreams(0)
Alex Ray7ee0b7a2012-11-06 00:12:49 -080051{
52 pthread_mutex_init(&mMutex,
53 NULL); // No pthread mutex attributes.
54
Alex Raya0ed4be2013-02-25 15:02:16 -080055 memset(&mDevice, 0, sizeof(mDevice));
Alex Ray7ee0b7a2012-11-06 00:12:49 -080056 mDevice.common.tag = HARDWARE_DEVICE_TAG;
Alex Ray7ee0b7a2012-11-06 00:12:49 -080057 mDevice.common.close = close_device;
Alex Raya0ed4be2013-02-25 15:02:16 -080058 mDevice.ops = const_cast<camera3_device_ops_t*>(&sOps);
Alex Ray7ee0b7a2012-11-06 00:12:49 -080059 mDevice.priv = this;
60}
61
62Camera::~Camera()
63{
64}
65
Alex Raya0ed4be2013-02-25 15:02:16 -080066int Camera::open(const hw_module_t *module, hw_device_t **device)
Alex Ray7ee0b7a2012-11-06 00:12:49 -080067{
Alex Raya0ed4be2013-02-25 15:02:16 -080068 ALOGI("%s:%d: Opening camera device", __func__, mId);
Alex Rayc16e56d2013-04-29 12:24:49 -070069 CAMTRACE_CALL();
Alex Ray7ee0b7a2012-11-06 00:12:49 -080070 pthread_mutex_lock(&mMutex);
71 if (mBusy) {
72 pthread_mutex_unlock(&mMutex);
Alex Raya0ed4be2013-02-25 15:02:16 -080073 ALOGE("%s:%d: Error! Camera device already opened", __func__, mId);
Alex Ray7ee0b7a2012-11-06 00:12:49 -080074 return -EBUSY;
75 }
76
77 // TODO: open camera dev nodes, etc
78 mBusy = true;
Alex Raya0ed4be2013-02-25 15:02:16 -080079 mDevice.common.module = const_cast<hw_module_t*>(module);
80 *device = &mDevice.common;
Alex Ray7ee0b7a2012-11-06 00:12:49 -080081
82 pthread_mutex_unlock(&mMutex);
83 return 0;
84}
85
86int Camera::close()
87{
Alex Raya0ed4be2013-02-25 15:02:16 -080088 ALOGI("%s:%d: Closing camera device", __func__, mId);
Alex Rayc16e56d2013-04-29 12:24:49 -070089 CAMTRACE_CALL();
Alex Ray7ee0b7a2012-11-06 00:12:49 -080090 pthread_mutex_lock(&mMutex);
91 if (!mBusy) {
92 pthread_mutex_unlock(&mMutex);
Alex Raya0ed4be2013-02-25 15:02:16 -080093 ALOGE("%s:%d: Error! Camera device not open", __func__, mId);
Alex Ray7ee0b7a2012-11-06 00:12:49 -080094 return -EINVAL;
95 }
96
97 // TODO: close camera dev nodes, etc
98 mBusy = false;
99
100 pthread_mutex_unlock(&mMutex);
101 return 0;
102}
103
Alex Raya0ed4be2013-02-25 15:02:16 -0800104int Camera::initialize(const camera3_callback_ops_t *callback_ops)
Alex Ray7ee0b7a2012-11-06 00:12:49 -0800105{
Alex Raya0ed4be2013-02-25 15:02:16 -0800106 ALOGV("%s:%d: callback_ops=%p", __func__, mId, callback_ops);
107 mCallbackOps = callback_ops;
Alex Ray7ee0b7a2012-11-06 00:12:49 -0800108 return 0;
109}
110
Alex Raybcaf7882013-02-28 16:04:35 -0800111int Camera::configureStreams(camera3_stream_configuration_t *stream_config)
Alex Ray7ee0b7a2012-11-06 00:12:49 -0800112{
Alex Raybcaf7882013-02-28 16:04:35 -0800113 camera3_stream_t *astream;
114 Stream **newStreams = NULL;
115
116 CAMTRACE_CALL();
117 ALOGV("%s:%d: stream_config=%p", __func__, mId, stream_config);
118
119 if (stream_config == NULL) {
120 ALOGE("%s:%d: NULL stream configuration array", __func__, mId);
121 return -EINVAL;
122 }
123 if (stream_config->num_streams == 0) {
124 ALOGE("%s:%d: Empty stream configuration array", __func__, mId);
125 return -EINVAL;
126 }
127
128 // Create new stream array
129 newStreams = new Stream*[stream_config->num_streams];
130 ALOGV("%s:%d: Number of Streams: %d", __func__, mId,
131 stream_config->num_streams);
132
133 pthread_mutex_lock(&mMutex);
134
135 // Mark all current streams unused for now
136 for (int i = 0; i < mNumStreams; i++)
137 mStreams[i]->mReuse = false;
138 // Fill new stream array with reused streams and new streams
139 for (int i = 0; i < stream_config->num_streams; i++) {
140 astream = stream_config->streams[i];
141 if (astream->max_buffers > 0)
142 newStreams[i] = reuseStream(astream);
143 else
144 newStreams[i] = new Stream(mId, astream);
145
146 if (newStreams[i] == NULL) {
147 ALOGE("%s:%d: Error processing stream %d", __func__, mId, i);
148 goto err_out;
149 }
150 astream->priv = newStreams[i];
151 }
152
153 // Verify the set of streams in aggregate
154 if (!isValidStreamSet(newStreams, stream_config->num_streams)) {
155 ALOGE("%s:%d: Invalid stream set", __func__, mId);
156 goto err_out;
157 }
158
159 // Set up all streams (calculate usage/max_buffers for each)
160 setupStreams(newStreams, stream_config->num_streams);
161
162 // Destroy all old streams and replace stream array with new one
163 destroyStreams(mStreams, mNumStreams);
164 mStreams = newStreams;
165 mNumStreams = stream_config->num_streams;
166
167 pthread_mutex_unlock(&mMutex);
Alex Raya0ed4be2013-02-25 15:02:16 -0800168 return 0;
Alex Raybcaf7882013-02-28 16:04:35 -0800169
170err_out:
171 // Clean up temporary streams, preserve existing mStreams/mNumStreams
172 destroyStreams(newStreams, stream_config->num_streams);
173 pthread_mutex_unlock(&mMutex);
174 return -EINVAL;
175}
176
177void Camera::destroyStreams(Stream **streams, int count)
178{
179 if (streams == NULL)
180 return;
181 for (int i = 0; i < count; i++) {
182 // Only destroy streams that weren't reused
183 if (streams[i] != NULL && !streams[i]->mReuse)
184 delete streams[i];
185 }
186 delete [] streams;
187}
188
189Stream *Camera::reuseStream(camera3_stream_t *astream)
190{
191 Stream *priv = reinterpret_cast<Stream*>(astream->priv);
192 // Verify the re-used stream's parameters match
193 if (!priv->isValidReuseStream(mId, astream)) {
194 ALOGE("%s:%d: Mismatched parameter in reused stream", __func__, mId);
195 return NULL;
196 }
197 // Mark stream to be reused
198 priv->mReuse = true;
199 return priv;
200}
201
202bool Camera::isValidStreamSet(Stream **streams, int count)
203{
204 int inputs = 0;
205 int outputs = 0;
206
207 if (streams == NULL) {
208 ALOGE("%s:%d: NULL stream configuration streams", __func__, mId);
209 return false;
210 }
211 if (count == 0) {
212 ALOGE("%s:%d: Zero count stream configuration streams", __func__, mId);
213 return false;
214 }
215 // Validate there is at most one input stream and at least one output stream
216 for (int i = 0; i < count; i++) {
217 // A stream may be both input and output (bidirectional)
218 if (streams[i]->isInputType())
219 inputs++;
220 if (streams[i]->isOutputType())
221 outputs++;
222 }
223 if (outputs < 1) {
224 ALOGE("%s:%d: Stream config must have >= 1 output", __func__, mId);
225 return false;
226 }
227 if (inputs > 1) {
228 ALOGE("%s:%d: Stream config must have <= 1 input", __func__, mId);
229 return false;
230 }
231 // TODO: check for correct number of Bayer/YUV/JPEG/Encoder streams
232 return true;
233}
234
235void Camera::setupStreams(Stream **streams, int count)
236{
237 /*
238 * This is where the HAL has to decide internally how to handle all of the
239 * streams, and then produce usage and max_buffer values for each stream.
240 * Note, the stream array has been checked before this point for ALL invalid
241 * conditions, so it must find a successful configuration for this stream
242 * array. The HAL may not return an error from this point.
243 *
244 * In this demo HAL, we just set all streams to be the same dummy values;
245 * real implementations will want to avoid USAGE_SW_{READ|WRITE}_OFTEN.
246 */
247 for (int i = 0; i < count; i++) {
248 uint32_t usage = 0;
249
250 if (streams[i]->isOutputType())
251 usage |= GRALLOC_USAGE_SW_WRITE_OFTEN |
252 GRALLOC_USAGE_HW_CAMERA_WRITE;
253 if (streams[i]->isInputType())
254 usage |= GRALLOC_USAGE_SW_READ_OFTEN |
255 GRALLOC_USAGE_HW_CAMERA_READ;
256
257 streams[i]->setUsage(usage);
258 streams[i]->setMaxBuffers(1);
259 }
Alex Raya0ed4be2013-02-25 15:02:16 -0800260}
261
262int Camera::registerStreamBuffers(const camera3_stream_buffer_set_t *buf_set)
263{
264 ALOGV("%s:%d: buffer_set=%p", __func__, mId, buf_set);
265 // TODO: register buffers with hardware
266 return 0;
267}
268
269const camera_metadata_t* Camera::constructDefaultRequestSettings(int type)
270{
271 ALOGV("%s:%d: type=%d", __func__, mId, type);
272 // TODO: return statically built default request
273 return NULL;
274}
275
276int Camera::processCaptureRequest(camera3_capture_request_t *request)
277{
278 ALOGV("%s:%d: request=%p", __func__, mId, request);
Alex Rayc16e56d2013-04-29 12:24:49 -0700279 CAMTRACE_CALL();
Alex Raya0ed4be2013-02-25 15:02:16 -0800280
281 if (request == NULL) {
282 ALOGE("%s:%d: NULL request recieved", __func__, mId);
Alex Raya0ed4be2013-02-25 15:02:16 -0800283 return -EINVAL;
Alex Ray7ee0b7a2012-11-06 00:12:49 -0800284 }
285
Alex Raya0ed4be2013-02-25 15:02:16 -0800286 // TODO: verify request; submit request to hardware
Alex Raya0ed4be2013-02-25 15:02:16 -0800287 return 0;
Alex Ray7ee0b7a2012-11-06 00:12:49 -0800288}
289
Alex Raya0ed4be2013-02-25 15:02:16 -0800290void Camera::getMetadataVendorTagOps(vendor_tag_query_ops_t *ops)
291{
292 ALOGV("%s:%d: ops=%p", __func__, mId, ops);
293 // TODO: return vendor tag ops
294}
295
296void Camera::dump(int fd)
297{
Alex Rayaf3a4612013-04-29 14:16:10 -0700298 ALOGV("%s:%d: Dumping to fd %d", __func__, mId, fd);
Alex Raya0ed4be2013-02-25 15:02:16 -0800299 // TODO: dprintf all relevant state to fd
300}
301
302extern "C" {
303// Get handle to camera from device priv data
304static Camera *camdev_to_camera(const camera3_device_t *dev)
305{
306 return reinterpret_cast<Camera*>(dev->priv);
307}
308
309static int initialize(const camera3_device_t *dev,
310 const camera3_callback_ops_t *callback_ops)
311{
312 return camdev_to_camera(dev)->initialize(callback_ops);
313}
314
315static int configure_streams(const camera3_device_t *dev,
316 camera3_stream_configuration_t *stream_list)
317{
318 return camdev_to_camera(dev)->configureStreams(stream_list);
319}
320
321static int register_stream_buffers(const camera3_device_t *dev,
322 const camera3_stream_buffer_set_t *buffer_set)
323{
324 return camdev_to_camera(dev)->registerStreamBuffers(buffer_set);
325}
326
327static const camera_metadata_t *construct_default_request_settings(
328 const camera3_device_t *dev, int type)
329{
330 return camdev_to_camera(dev)->constructDefaultRequestSettings(type);
331}
332
333static int process_capture_request(const camera3_device_t *dev,
334 camera3_capture_request_t *request)
335{
336 return camdev_to_camera(dev)->processCaptureRequest(request);
337}
338
339static void get_metadata_vendor_tag_ops(const camera3_device_t *dev,
340 vendor_tag_query_ops_t *ops)
341{
342 camdev_to_camera(dev)->getMetadataVendorTagOps(ops);
343}
344
345static void dump(const camera3_device_t *dev, int fd)
346{
347 camdev_to_camera(dev)->dump(fd);
348}
349} // extern "C"
350
351const camera3_device_ops_t Camera::sOps = {
352 .initialize = default_camera_hal::initialize,
353 .configure_streams = default_camera_hal::configure_streams,
354 .register_stream_buffers = default_camera_hal::register_stream_buffers,
355 .construct_default_request_settings =
356 default_camera_hal::construct_default_request_settings,
357 .process_capture_request = default_camera_hal::process_capture_request,
358 .get_metadata_vendor_tag_ops =
359 default_camera_hal::get_metadata_vendor_tag_ops,
360 .dump = default_camera_hal::dump
361};
362
Alex Ray7ee0b7a2012-11-06 00:12:49 -0800363} // namespace default_camera_hal