diff options
author | Alex Ray <aray@google.com> | 2012-11-06 00:12:49 -0800 |
---|---|---|
committer | Alex Ray <aray@google.com> | 2012-11-28 12:35:29 -0800 |
commit | 7ee0b7aac252dd2758e9344c12cf5f72415c5ace (patch) | |
tree | 816269df4c863611b694d4989270a8ace9782527 /modules/camera | |
parent | 2a4caa5856e7e627e42daf12b6b551515c8fff27 (diff) | |
download | hardware_libhardware-7ee0b7aac252dd2758e9344c12cf5f72415c5ace.zip hardware_libhardware-7ee0b7aac252dd2758e9344c12cf5f72415c5ace.tar.gz hardware_libhardware-7ee0b7aac252dd2758e9344c12cf5f72415c5ace.tar.bz2 |
Reference Camera v2 HAL Implementation
This is meant to be an example and a reference for device manufacturers
on how to build a new Camera v2 HAL. This first patch has basic
configuration and entry/exit.
Change-Id: Ib4166e2eadb813228af38ec31a1215940c070bbf
Diffstat (limited to 'modules/camera')
-rw-r--r-- | modules/camera/Android.mk | 37 | ||||
-rw-r--r-- | modules/camera/Camera.cpp | 120 | ||||
-rw-r--r-- | modules/camera/Camera.h | 63 | ||||
-rw-r--r-- | modules/camera/CameraHAL.cpp | 108 |
4 files changed, 328 insertions, 0 deletions
diff --git a/modules/camera/Android.mk b/modules/camera/Android.mk new file mode 100644 index 0000000..aa457f4 --- /dev/null +++ b/modules/camera/Android.mk @@ -0,0 +1,37 @@ +# Copyright (C) 2012 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE := camera.default +LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw + +LOCAL_C_INCLUDES += \ + system/media/camera/include \ + +LOCAL_SRC_FILES := \ + CameraHAL.cpp \ + Camera.cpp \ + +LOCAL_SHARED_LIBRARIES := \ + libcamera_metadata \ + liblog \ + +LOCAL_CFLAGS += -Wall -Wextra + +LOCAL_MODULE_TAGS := optional + +include $(BUILD_SHARED_LIBRARY) diff --git a/modules/camera/Camera.cpp b/modules/camera/Camera.cpp new file mode 100644 index 0000000..24cfe4f --- /dev/null +++ b/modules/camera/Camera.cpp @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <cstdlib> +#include <pthread.h> + +#define LOG_NDEBUG 0 +#define LOG_TAG "Camera" +#include <cutils/log.h> + +#include "Camera.h" + +namespace default_camera_hal { + +extern "C" { +// Shim passed to the framework to close an opened device. +static int close_device(hw_device_t* dev) +{ + camera2_device_t* cam_dev = reinterpret_cast<camera2_device_t*>(dev); + Camera* cam = static_cast<Camera*>(cam_dev->priv); + return cam->close(); +} +} // extern "C" + +Camera::Camera(int id, const hw_module_t* module) + : mId(id), + mBusy(false), + mMetadata(NULL) +{ + pthread_mutex_init(&mMutex, + NULL); // No pthread mutex attributes. + + // TODO: fill in device operations function pointers + mDevice.common.tag = HARDWARE_DEVICE_TAG; + mDevice.common.module = const_cast<hw_module_t*>(module); + mDevice.common.close = close_device; + mDevice.priv = this; +} + +Camera::~Camera() +{ +} + +int Camera::open() +{ + ALOGV("%s: camera id %d", __func__, mId); + pthread_mutex_lock(&mMutex); + if (mBusy) { + pthread_mutex_unlock(&mMutex); + ALOGE("%s:id%d: Error, device already in use.", __func__, mId); + return -EBUSY; + } + + // TODO: open camera dev nodes, etc + mBusy = true; + + pthread_mutex_unlock(&mMutex); + return 0; +} + +int Camera::close() +{ + ALOGV("%s: camera id %d", __func__, mId); + pthread_mutex_lock(&mMutex); + if (!mBusy) { + pthread_mutex_unlock(&mMutex); + ALOGE("%s:id%d: Error, close() on not open device.", __func__, mId); + return -EINVAL; + } + + // TODO: close camera dev nodes, etc + mBusy = false; + + pthread_mutex_unlock(&mMutex); + return 0; +} + +int Camera::getCameraInfo(struct camera_info* info) +{ + ALOGV("%s: camera id %d: info=%p", __func__, mId, info); + init(); + if (mMetadata == NULL) { + ALOGE("%s:id%d: unable to initialize metadata.", __func__, mId); + return -ENOENT; + } + + // TODO: fill remainder of info struct + info->static_camera_characteristics = mMetadata; + + return 0; +} + +void Camera::init() +{ + pthread_mutex_lock(&mMutex); + if (mMetadata != NULL) { + pthread_mutex_unlock(&mMutex); + return; + } + + // TODO: init metadata, dummy value for now + mMetadata = allocate_camera_metadata(1,1); + + pthread_mutex_unlock(&mMutex); +} + +} // namespace default_camera_hal diff --git a/modules/camera/Camera.h b/modules/camera/Camera.h new file mode 100644 index 0000000..72cbde2 --- /dev/null +++ b/modules/camera/Camera.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CAMERA_H_ +#define CAMERA_H_ + +#include <pthread.h> +#include <hardware/camera2.h> + +namespace default_camera_hal { +// Camera represents a physical camera on a device. +// This is constructed when the HAL module is loaded, one per physical camera. +// It is opened by the framework, and must be closed before it can be opened +// again. +// Also, the framework can query for camera metadata with getCameraInfo. +// For the first query, the metadata must first be allocated and initialized, +// but once done it is used for all future calls. +// It is protected by @mMutex, and functions that modify the Camera object hold +// this lock when performing modifications. Currently these functions are: +// @open, @close, and @init. +class Camera { + public: + // id is used to distinguish cameras. 0 <= id < NUM_CAMERAS. + // module is a handle to the HAL module, used when the device is opened. + Camera(int id, const hw_module_t* module); + ~Camera(); + // Open this camera, preparing it for use. Returns nonzero on failure. + int open(); + // Close this camera. Returns nonzero on failure. + int close(); + // Query for camera metadata, filling info struct. Returns nonzero if + // allocation or initialization failed. + int getCameraInfo(struct camera_info* info); + // Handle to this device passed to framework in response to open(). + camera2_device_t mDevice; + private: + // One-time initialization of camera metadata. + void init(); + // Identifier used by framework to distinguish cameras + int mId; + // True indicates camera is already open. + bool mBusy; + // Camera characteristics. NULL means it has not been allocated yet. + camera_metadata_t* mMetadata; + // Lock protecting the Camera object for modifications + pthread_mutex_t mMutex; +}; +} // namespace default_camera_hal + +#endif // CAMERA_H_ diff --git a/modules/camera/CameraHAL.cpp b/modules/camera/CameraHAL.cpp new file mode 100644 index 0000000..22c7aef --- /dev/null +++ b/modules/camera/CameraHAL.cpp @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <cstdlib> +#include <hardware/camera2.h> + +//#define LOG_NDEBUG 0 +#define LOG_TAG "CameraHAL" +#include <cutils/log.h> + +#include "Camera.h" + +/* + * This file serves as the entry point to the HAL. It contains the module + * structure and functions used by the framework to load and interface to this + * HAL, as well as the handles to the individual camera devices. + */ + +namespace default_camera_hal { + +enum camera_id_t { + CAMERA_A, + CAMERA_B, + NUM_CAMERAS +}; + +// Symbol used by the framework when loading the HAL, defined below. +extern "C" camera_module_t HAL_MODULE_INFO_SYM; + +// Camera devices created when the module is loaded. See Camera.h +static Camera gCameras[NUM_CAMERAS] = { + Camera(CAMERA_A, &HAL_MODULE_INFO_SYM.common), + Camera(CAMERA_B, &HAL_MODULE_INFO_SYM.common) +}; + +extern "C" { + +static int get_number_of_cameras() +{ + ALOGV("%s", __func__); + return NUM_CAMERAS; +} + +static int get_camera_info(int id, struct camera_info* info) +{ + ALOGV("%s: camera id %d: info=%p", __func__, id, info); + if (id < 0 || id >= NUM_CAMERAS) { + ALOGE("%s: Invalid camera id %d", __func__, id); + return -ENODEV; + } + return gCameras[id].getCameraInfo(info); +} + +static int open_device(const hw_module_t* module, + const char* name, + hw_device_t** device) +{ + ALOGV("%s: module=%p, name=%s, device=%p", __func__, module, name, device); + char *nameEnd; + int id; + + id = strtol(name, &nameEnd, 10); + if (nameEnd != NULL) { + ALOGE("%s: Invalid camera id name %s", __func__, name); + return -EINVAL; + } else if (id < 0 || id >= NUM_CAMERAS) { + ALOGE("%s: Invalid camera id %d", __func__, id); + return -ENODEV; + } + *device = &gCameras[id].mDevice.common; + return gCameras[id].open(); +} + +static hw_module_methods_t gCameraModuleMethods = { + open : open_device +}; + +camera_module_t HAL_MODULE_INFO_SYM = { + common : { + tag : HARDWARE_MODULE_TAG, + module_api_version : CAMERA_MODULE_API_VERSION_2_0, + hal_api_version : HARDWARE_HAL_API_VERSION, + id : CAMERA_HARDWARE_MODULE_ID, + name : "Reference Camera v2 HAL", + author : "The Android Open Source Project", + methods : &gCameraModuleMethods, + dso : NULL, + reserved : {0}, + }, + get_number_of_cameras : get_number_of_cameras, + get_camera_info : get_camera_info +}; + +} // extern "C" +} // namespace default_camera_hal |