Camera.cpp revision bcaf788434b0f4fcc4f194ca01d94cd59eb912a9
1/*
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>
19#include <hardware/camera3.h>
20#include "CameraHAL.h"
21#include "Stream.h"
22
23//#define LOG_NDEBUG 0
24#define LOG_TAG "Camera"
25#include <cutils/log.h>
26
27#define ATRACE_TAG (ATRACE_TAG_CAMERA | ATRACE_TAG_HAL)
28#include <cutils/trace.h>
29#include "ScopedTrace.h"
30
31#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{
39    camera3_device_t* cam_dev = reinterpret_cast<camera3_device_t*>(dev);
40    Camera* cam = static_cast<Camera*>(cam_dev->priv);
41    return cam->close();
42}
43} // extern "C"
44
45Camera::Camera(int id)
46  : mId(id),
47    mBusy(false),
48    mCallbackOps(NULL),
49    mStreams(NULL),
50    mNumStreams(0)
51{
52    pthread_mutex_init(&mMutex,
53                       NULL); // No pthread mutex attributes.
54
55    memset(&mDevice, 0, sizeof(mDevice));
56    mDevice.common.tag    = HARDWARE_DEVICE_TAG;
57    mDevice.common.close  = close_device;
58    mDevice.ops           = const_cast<camera3_device_ops_t*>(&sOps);
59    mDevice.priv          = this;
60}
61
62Camera::~Camera()
63{
64}
65
66int Camera::open(const hw_module_t *module, hw_device_t **device)
67{
68    ALOGI("%s:%d: Opening camera device", __func__, mId);
69    CAMTRACE_CALL();
70    pthread_mutex_lock(&mMutex);
71    if (mBusy) {
72        pthread_mutex_unlock(&mMutex);
73        ALOGE("%s:%d: Error! Camera device already opened", __func__, mId);
74        return -EBUSY;
75    }
76
77    // TODO: open camera dev nodes, etc
78    mBusy = true;
79    mDevice.common.module = const_cast<hw_module_t*>(module);
80    *device = &mDevice.common;
81
82    pthread_mutex_unlock(&mMutex);
83    return 0;
84}
85
86int Camera::close()
87{
88    ALOGI("%s:%d: Closing camera device", __func__, mId);
89    CAMTRACE_CALL();
90    pthread_mutex_lock(&mMutex);
91    if (!mBusy) {
92        pthread_mutex_unlock(&mMutex);
93        ALOGE("%s:%d: Error! Camera device not open", __func__, mId);
94        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
104int Camera::initialize(const camera3_callback_ops_t *callback_ops)
105{
106    ALOGV("%s:%d: callback_ops=%p", __func__, mId, callback_ops);
107    mCallbackOps = callback_ops;
108    return 0;
109}
110
111int Camera::configureStreams(camera3_stream_configuration_t *stream_config)
112{
113    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);
168    return 0;
169
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    }
260}
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);
279    CAMTRACE_CALL();
280
281    if (request == NULL) {
282        ALOGE("%s:%d: NULL request recieved", __func__, mId);
283        return -EINVAL;
284    }
285
286    // TODO: verify request; submit request to hardware
287    return 0;
288}
289
290void 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{
298    ALOGV("%s:%d: Dumping to fd %d", __func__, mId, fd);
299    // 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
363} // namespace default_camera_hal
364